/* * Implementation of EntityStrBrowser. */ #include #include #include #include #include #include #include #include "paintlabel.h" #include "rstrbrowser.h" EntityStrBrowser::EntityStrBrowser(RSLBrowser* browser, int rows, int cols, EntityStructList* sl) : LStringBrowser(new ButtonState(), rows, cols) { /* * Construct and call InstallNames with the given entity struct list. In * current imple, list will be empty. */ this->browser = browser; symtab = new EntitySymtab(); InstallNames(sl); } EntityStrBrowser* EntityStrBrowser::InstallNames(EntityStructList* el) { /* * Stick the strings in the given list into this. Also, make a symtab * containing the names for subsequent efficient lookup by name. For now, name * lookup only happens when someone types directly in the cur entity str ed, * which probably doesnt happen that often. However, it's good to have an * efficient lookup tab laying around for possible future expansion. * * * NOTE: if we could easily specialize the elems of a str browser to be * EntityStruct* rather that char*, we wouldnt need this function. Rather, * callers would use Append incrementally rather than building a list and * having the Appends done here. See the design note in * rslbrowser.c:RSLBrowser::InstallNames for more details. */ EntityStruct* e; /* Temp ptr */ /* * Clear out any extant strings. */ Clear(); /* * Keep the entity struct list around for later use. See this::Handle. */ this->el = el; /* * Foreach entity in the list, append its (disambiguated) name onto this * and enter it into the symtab. */ if (el) { while (e = (EntityStruct*) el->Enum()) { Append(e->GetName()); symtab->EnterSym(e); } } return this; } EntityStrBrowser* EntityStrBrowser::ScrollToName(EntityStruct *es) { /* if (this->es->GetSym() != es->GetSym()) { */ int i = Index(es->GetName()); if (this->es) { Unselect(Index(this->es->GetName())); } Select(i); ScrollTo(i); this->es = es; /* } */ return this; } void EntityStrBrowser::Handle(Event& e) { if (not el) return; if (e.eventType == KeyEvent) { HandleKeyEvent(e); } else { bool done = false; do { switch (e.eventType) { case DownEvent: done = HandleDownEvent(e); /* NEW for EntityStrBrowser */ if (not done) /* SUBTLE! See CHANGELOG */ { es = el->GetNth(Selection(0)+1); if (es) browser->UpdateCurEntity(es); } /* END NEW */ break; case KeyEvent: done = HandleKeyEvent(e); break; } if (!done) { if (browser->MenubarNeedsUpdating()) { browser->UpdateMenuBar(es); /*browser->Change(browser->menuBar);*/ } Read(e); } } while (!done); } } bool EntityStrBrowser::HandleDownEvent (Event& e) { bool done = true; if (e.target == this) { if (e.button == LEFTMOUSE) { done = LeftButtonDown(e); } else if (e.button == MIDDLEMOUSE) { GrabScroll(e); } else if (e.button == RIGHTMOUSE) { RateScroll(e); } } else { UnRead(e); } return done; } bool EntityStrBrowser::HandleKeyEvent (Event& e) { bool done = false; if (e.len != 0) { done = HandleChar(e.keystring[0]); } return done; } EntityStrBrowserPair::EntityStrBrowserPair(RSLBrowser* browser, int rows, int cols) { /* * Obvious. */ objs = new EntityStrBrowser(browser, rows, cols); ops = new EntityStrBrowser(browser, rows, cols); this->browser = browser; } EntityStrBrowser* EntityStrBrowserPair::InstallObjs(EntityStructList* el) { objs->InstallNames(el); return objs; } EntityStrBrowser* EntityStrBrowserPair::InstallOps(EntityStructList* el) { ops->InstallNames(el); return ops; } EntityStrBrowserPair* EntityStrBrowserPair::ScrollToName(EntityStruct *es) { switch (es->GetSym()->Class) { case C_Obj: /* objs->UnselectAll(); */ /* objs->Reconfig(); protected */ objs->ScrollToName(es); ops->UnselectAll(); break; case C_Op: /* ops->UnselectAll(); */ /* ops->Reconfig(); protected */ ops->ScrollToName(es); objs->UnselectAll(); break; case C_Module: objs->UnselectAll(); ops->UnselectAll(); break; } return this; } Box* EntityStrBrowserPair::Layout() { return Layout(round(0.15*inch)); } Box* EntityStrBrowserPair::Layout(int distanceInInchesToOpsBrowser) { HBox* objsInnerBox = new HBox(); HBox* opsInnerBox = new HBox(); VBox* objsOuterBox = new VBox(); VBox* opsOuterBox = new VBox(); HBox* edsBox = new HBox(); VBox* objsVscrl = new VBox( new HBorder, new UpMover(objs,1), new HBorder, new VScroller(objs), new HBorder, new DownMover(objs,1)); VBox* opsVscrl = new VBox( new HBorder, new UpMover(ops,1), new HBorder, new VScroller(ops), new HBorder, new DownMover(ops,1)); HBox* objsHscrl = new HBox( new VBorder, new LeftMover(objs,1), new VBorder, new HScroller(objs), new VBorder, new RightMover(objs,1), new VBorder); HBox* opsHscrl = new HBox( new VBorder, new LeftMover(ops,1), new VBorder, new HScroller(ops), new VBorder, new RightMover(ops,1), new VBorder); objsOuterBox->Insert(new PaintLabel("Objects:", "times", "bold", "r", "14")); objsInnerBox->Insert(new Frame(objs)); objsInnerBox->Insert(new VBorder); objsInnerBox->Insert(objsVscrl); objsOuterBox->Insert(objsInnerBox); objsOuterBox->Insert(new HBorder); objsOuterBox->Insert(objsHscrl); opsOuterBox->Insert(new PaintLabel("Operations:", "times", "bold", "r", "14")); opsInnerBox->Insert(new Frame(ops)); opsInnerBox->Insert(new VBorder); opsInnerBox->Insert(opsVscrl); opsOuterBox->Insert(opsInnerBox); opsOuterBox->Insert(new HBorder); opsOuterBox->Insert(opsHscrl); edsBox->Insert(new Frame(objsOuterBox)); edsBox->Insert(new HGlue(distanceInInchesToOpsBrowser)); edsBox->Insert(new Frame (opsOuterBox)); return edsBox; } inline EntityStrBrowser* EntityStrBrowserPair::GetObjs() { return objs; } inline EntityStrBrowser* EntityStrBrowserPair::GetOps() { return ops; } inline EntitySymtab* EntityStrBrowser::GetSymtab() { return symtab; } void EntityStrBrowser::Resize() { /*register Perspective* p = perspective;*/ LStringBrowser::Resize(); /*p->width = (columns+20) * shape->hunits;*/ } EntityStruct* EntityStrBrowserPair::Lookup(const char* ename) { /* * Strip off the "object" or "operation" prefix and bifarcate thereupon. */ char* cp; int l = strlen(ename) + 1; char* s0 = strcpy(new char[l], ename); /* * Strip off trailing blanks (what an f'ing pain). */ for (cp = &(s0[l]); (*cp == ' ') or (*cp == '\0'); cp--) { if (*cp == ' ') l--; *cp = '\0'; } char* s1 = strcpy(new char[l], ename); char* s2 = index(s1, ' '); s2++; char* s3 = strtok(s1, " "); if (streq(s3, "object")) return objs->GetSymtab()->LookupSym(s2); else if (streq(s3, "operation")) return ops->GetSymtab()->LookupSym(s2); else { char* msg = new char[l + strlen("Cannot find in current module scope")]; sprintf(msg, "Cannot find %s in current module scope", s0); browser->ErrorDialog(msg); delete msg; return null; } } EntityStrBrowserPair* EntityStrBrowserPair::Unselect() { /* * Unselect anything that's on in either stred. */ objs->UnselectAll(); ops->UnselectAll(); return this; }