/**** * * WARNING: This file should be identical (below this warning) with menus.C. * It used to be a sym link, but now it's a copy for CVS check in. The * existence of this copy under a different name is for use in the Makefile to * generate a .o file with a different root name, which is built with different * -D settings. I.e., menus.o and nmenus.o are different object files, built * from a common source with different -D settings. It may be unnecessary to * do it this way, but don't worry about it. * */ /* * Implementation of RSLMenuBar and friends. (That's "friends" in the Rocky * and Bullwinkle sense, not the C++ sense). */ #include #include "menus.h" #ifndef RBROWSEONLY // #include "editor.h" // #include "windowaccess.h" /* For GetLiveWin() */ #endif #include "systest.h" // #include /* For signature of max (how mnemonic (NOT)) */ RSLMenuBar::RSLMenuBar(RSLBrowser* browser, TransInterface* ti, exception* exitExc) { this->browser = browser; this->ti = ti; Init(exitExc); } void RSLMenuBar::Init(exception* exitExc) { InitDialogs(); InitPulldowns(exitExc); InitBars(); InitScene(); } void RSLMenuBar::InitPulldowns(exception* exitExc) { InitFile(exitExc); InitModules(); InitComponents(); InitParents(); InitInstances(); InitInstanceof(); InitOperations(); InitInputs(); InitOutputs(); InitLinks(); InitOptions(); } void RSLMenuBar::InitBars() { InitInit(); InitObj(); InitOp(); InitTransient(); } void RSLMenuBar::InitScene() { box = new HBox(initBar); curBar = initBar; Insert(box); } void RSLMenuBar::InitDialogs() { fileDialog = new FileDialog(browser); filelistDialog = new FileListDialog(browser); fsearchDialog = new SearchDialog(browser, "Search forward for"); bsearchDialog = new SearchDialog(browser, "Search backward for"); gsearchDialog = new SearchDialog(browser, "Goto line"); } StateVisibleMenuBar* RSLMenuBar::InitInit() { initBar = new StateVisibleMenuBar(); initBar->Include(file); initBar->Include(modules); initBar->Include(options); return initBar; } StateVisibleMenuBar* RSLMenuBar::InitObj() { objBar = new StateVisibleMenuBar(); objBar->Include(file); objBar->Include(modules); objBar->Include(components); objBar->Include(parents); objBar->Include(instances); objBar->Include(instanceof); objBar->Include(operations); objBar->Include(links); objBar->Include(options); return objBar; } StateVisibleMenuBar* RSLMenuBar::InitOp() { opBar = new StateVisibleMenuBar(); opBar->Include(file); opBar->Include(modules); opBar->Include(components); opBar->Include(parents); opBar->Include(instances); opBar->Include(instanceof); opBar->Include(inputs); opBar->Include(outputs); opBar->Include(links); opBar->Include(options); return opBar; } StateVisibleMenuBar* RSLMenuBar::InitTransient() { transientBar = new StateVisibleMenuBar(); return transientBar; } FileMenu* RSLMenuBar::InitFile(exception* exitExc) { file = new FileMenu("File "); file->Include(new OpenMenuItem(browser, fileDialog)); closesubmenu = new CloseMenuItem(browser); file->Include(closesubmenu); exposesubmenu = new ExposeMenuItem(browser); file->Include(exposesubmenu); file->Include(new SaveMenuItem(browser)); file->Include(new SaveAsMenuItem(browser, fileDialog)); file->Include(new SaveAllMenuItem(browser)); file->Include(new RescanMenuItem(browser)); file->Include(new SearchForwMenuItem(browser, fsearchDialog)); file->Include(new SearchBackMenuItem(browser, bsearchDialog)); file->Include(new GotoLineMenuItem(browser, gsearchDialog)); file->Include(new QuitMenuItem(browser, exitExc)); file->Include(new TestMenuItem(browser)); return file; } ModulesMenu* RSLMenuBar::InitModules() { /* * Install a new set of names in the Modules pulldown. */ modules = new ModulesMenu("Modules ", browser); return modules; } ComponentsMenu* RSLMenuBar::InitComponents() { components = new ComponentsMenu("Components ", browser); return components; } ParentsMenu* RSLMenuBar::InitParents() { parents = new ParentsMenu("Parents ", browser); return parents; } InstancesMenu* RSLMenuBar::InitInstances() { instances = new InstancesMenu("Instances ", browser); return instances; } InstanceofMenu* RSLMenuBar::InitInstanceof() { instanceof = new InstanceofMenu("InstanceOf ", browser); return instanceof; } OpsMenu* RSLMenuBar::InitOperations() { operations = new OpsMenu("Ops ", browser); return operations; } InsMenu* RSLMenuBar::InitInputs() { inputs = new InsMenu("Ins ", browser); return inputs; } OutsMenu* RSLMenuBar::InitOutputs() { outputs = new OutsMenu("Outs ", browser); return outputs; } LinksMenu* RSLMenuBar::InitLinks() { links = new LinksMenu("Links ", browser); return links; } OptionsMenu* RSLMenuBar::InitOptions() { options = new OptionsMenu("Options "); options->Include(new EditBrowseModeMenuItem(browser)); options->Include(new TransientMenusMenuItem(browser, this)); options->Include(new AutoGraphicsMenuItem(browser)); transflagssubmenu = new TranslatorFlagsMenuItem(browser); options->Include(transflagssubmenu); options->Include(new RedrawMenuItem(browser)); return options; } void RSLMenuBar::InstallModules(EntityStructList* el) { modules->InstallNames(el); } StateVisibleMenuBar* RSLMenuBar::UpdateObjMenuBar(EntityStruct* es) { /* * Get the goods for the given entity struct via the translator interface, q.v. * As the goods are got, pass them on to Install{Names, Parents,Links} to do * the work. */ components->InstallNames(ti->GetComponents(es->GetSym())); parents->InstallNames(ti->GetParents(es->GetSym())); instances->InstallNames(ti->GetInstances(es->GetSym())); instanceof->InstallNames(ti->GetClassParents(es->GetSym())); operations->InstallNames(ti->GetOperations(es->GetSym())); links->InstallNames(ti->GetLinks(es->GetSym())); return ComposeObjUpdates(); } StateVisibleMenuBar* RSLMenuBar::UpdateOpMenuBar(EntityStruct* es) { /* * Ibid. */ components->InstallNames(ti->GetComponents(es->GetSym())); parents->InstallNames(ti->GetParents(es->GetSym())); instances->InstallNames(ti->GetInstances(es->GetSym())); instanceof->InstallNames(ti->GetClassParents(es->GetSym())); inputs->InstallNames(ti->GetInputs(es->GetSym())); outputs->InstallNames(ti->GetOutputs(es->GetSym())); links->InstallNames(ti->GetLinks(es->GetSym())); return ComposeOpUpdates(); } StateVisibleMenuBar* RSLMenuBar::UpdateModuleMenuBar(EntityStruct* es) { /* * Return to the intial menu when a name from the Modules menu is chosen. */ box->Remove(curBar); box->Insert(initBar); box->Change(); /* Box::Reconfig is protected in this context */ Change(box); Draw(); curBar = initBar; return initBar; } void RSLMenuBar::AddToFileMenuList(const char* filename) { /* * Update the pullrighters used to list current open files (in File.Close * and File.Expose). */ CloseSubMenuMenuItem* sibling = new CloseSubMenuMenuItem(newstr(filename), browser); closesubmenu->Include(sibling); exposesubmenu->Include( new ExposeSubMenuMenuItem(newstr(filename), browser, sibling)); /* * PREVIOUS VEIN ATTEMPTS. Evidently, ClearScene messes something up. I * suspect something to do with some underlying state that is shared by main * menubar, which goes off when the main menubar changes. * * const char* fn; Interactor** a; CloseSubMenuMenuItem* i; int n = 0; Scene* s = closesubmenu->GetScene(); if (s) s->GetComponents(null, -1, a, n); if (n) { for (i = (CloseSubMenuMenuItem*) *a; n; n--, a++) { printf("Next CloseSubMenuMenuItem: %s", i->name); } } closesubmenu->ClearScene(); exposesubmenu->ClearScene(); while (fn = browser->EnumFiles()) { closesubmenu->Include(new CloseSubMenuMenuItem(filename, browser)); exposesubmenu->Include(new ExposeSubMenuMenuItem(filename, browser)); } */ } void RSLMenuBar::DeleteFromFileMenuList(const char* filename) { /* * To delete, find the suckers and do it. What a f---ing pain. */ Interactor** a; ExposeSubMenuMenuItem* i; int n = 0; Scene* s = exposesubmenu->GetScene(); if (s) s->GetComponents(null, -1, a, n); if (n) { for (i = (ExposeSubMenuMenuItem*) *a; n; i = (ExposeSubMenuMenuItem*) *(++a), n--) { if (streq(i->GetName(), filename)) { break; } } } else return; exposesubmenu->Remove(i); closesubmenu->Remove(i->GetSibling()); /* * NOTE WELL: * the following two deletes reek major havoc on the close menu. * Evidently, some iv destructor is bogus somewhere. * delete i; delete i->GetSibling(); * */ } void RSLMenuBar::UpdateFileMenuList(StrList* filenamelist) { const char* fn; while (fn = browser->EnumTFiles()) { CloseSubMenuMenuItem* sibling = new CloseSubMenuMenuItem(fn, browser); closesubmenu->Include(sibling); exposesubmenu->Include( new ExposeSubMenuMenuItem(fn, browser, sibling)); } } void RSLMenuBar::UpdateArgMenuList(int argc, char** argv) { /* * Update the pullrighter used to list translator args (in * Options.TranslatorFlags). */ } StateVisibleMenuBar* RSLMenuBar::ComposeObjUpdates() { /* * After each indiv menu has been updated, put them in a menubar. If * transient menus mode is one, install only non-null menus. */ if (browser->InTransientMenusMode()) return ComposeTransientObjUpdates(); /* * Fix the states of each menubar item. */ ControlState* s = objBar->GetState(); file->SetState(s); modules->SetState(s); components->SetState(s); parents->SetState(s); instances->SetState(s); instanceof->SetState(s); operations->SetState(s); links->SetState(s); options->SetState(s); /* * Should be able to do less than this, and have it happen immediately, but * cant figure out how. Viz., the effects of these changes are somehow put * on the X event queue, and they don't happen until some future event is * read and processed. This causes a visible flicker when the menubar is * updated. This is still a MAJOR thorn in the side of your programmer. */ box->Remove(curBar); box->Insert(objBar); box->Change(); Change(box); Draw(); curBar = objBar; return objBar; /* * OLDER APPROACH, which fails. * * Remove ins/outs menus if they're there. * Include(components, 2); Include(parents, 3); Include(instances, 4); Include(instanceof, 5); Include(operations, 6); Include(links, 7); browser->Change(); return this; */ } StateVisibleMenuBar* RSLMenuBar::ComposeOpUpdates() { /* * As ComposeOpUpdates, but install ins and outs instead of ops menu. */ if (browser->InTransientMenusMode()) return ComposeTransientOpUpdates(); ControlState* s = opBar->GetState(); file->SetState(s); modules->SetState(s); components->SetState(s); parents->SetState(s); instances->SetState(s); instanceof->SetState(s); inputs->SetState(s); outputs->SetState(s); links->SetState(s); options->SetState(s); box->Remove(curBar); box->Insert(opBar); box->Change(); Change(box); curBar = opBar; return opBar; } StateVisibleMenuBar* RSLMenuBar::ComposeTransientObjUpdates() { /* delete transientBar; */ transientBar = new StateVisibleMenuBar(); transientBar->Include(file); transientBar->Include(modules); if (components->Size() > 0) transientBar->Include(components); if (parents->Size() > 0) transientBar->Include(parents); if (instances->Size() > 0) transientBar->Include(instances); if (instanceof->Size() > 0) transientBar->Include(instanceof); if (operations->Size() > 0) transientBar->Include(operations); if (links->Size() > 0) transientBar->Include(links); transientBar->Include(options); box->Remove(curBar); box->Insert(transientBar); box->Change(); Change(box); Draw(); curBar = transientBar; return transientBar; } StateVisibleMenuBar* RSLMenuBar::ComposeTransientOpUpdates() { /* delete transientBar; */ transientBar = new StateVisibleMenuBar(); transientBar->Include(file); transientBar->Include(modules); if (components->Size() > 0) transientBar->Include(components); if (parents->Size() > 0) transientBar->Include(parents); if (instances->Size() > 0) transientBar->Include(instances); if (instanceof->Size() > 0) transientBar->Include(instanceof); if (inputs->Size() > 0) transientBar->Include(inputs); if (outputs->Size() > 0) transientBar->Include(outputs); if (links->Size() > 0) transientBar->Include(links); transientBar->Include(options); box->Remove(curBar); box->Insert(transientBar); box->Change(); Change(box); Draw(); curBar = transientBar; return transientBar; } NameListPulldownMenu::NameListPulldownMenu( const char* name, RSLBrowser* browser) : PulldownMenu(name) { this->browser = browser; } NameListPulldownMenu* NameListPulldownMenu::InstallNames(EntityStructList* newnames) { /* * Nuke the old names, if any, and install a new set. As described in the .h * file, there is a 1-1 coorespondence between items in the menu and an entity * struct list. */ VBox* newScene = new VBox(); EntityStruct* e; /* * ClearScene() is a new function in Menu to clear out the items. Cf. * the orig menu.{h,c} vs ./nmenu.{h,c}. * * NOT. Want to stick with standard version of lib. See SetScene below. * * NOT NOT. Cant get to work easily without ClearScene; too many iv lib * members are private. */ ClearScene(); /**/ if (newnames) { while (e = (EntityStruct*) newnames->Enum()) { Include(new NameListMenuItem(e->GetName(), e, browser)); // newScene->Insert(new NameListMenuItem(e->GetName(), e, browser)); } } /* * Replacement for ClearScene above. * SetScene(newScene); */ /* * Virtual destructors evidently dont work in g++-1.39. Fix when all is * moved to version 2+. * if (namelist) delete namelist; */ namelist = newnames; return this; } ModulesMenu* ModulesMenu::InstallNames(EntityStructList* newnames) { /* * A la NameListPulldownMenu::InstallNames, but checks module Main biznis. */ VBox* newScene = new VBox(); EntityStruct* e; ClearScene(); if (newnames) { while (e = (EntityStruct*) newnames->Enum()) { if (not ChkMain(e)) Include(new NameListMenuItem(e->GetName(), e, browser)); } } /* * Virtual destructors evidently dont work in g++-1.39. Fix when all is * moved to version 2+. * if (namelist) delete namelist; */ namelist = newnames; return this; } bool ModulesMenu::ChkMain(EntityStruct* es) { if (streq(es->GetName(), "Main")) { return /*IsMainListEmpty();*/ true; } return false; } LinksMenuItem::LinksMenuItem( const char* name, RSLBrowser* browser) : PullrightMenu(name) { this->browser = browser; } LinksMenuItem* LinksMenuItem::InstallNames(EntityStructList* newnames, char* parentname) { /* * Just like NameListMenuItem::InstallNames with the exception of passing * parentname, which is used to determine if the link is a picture or * not. */ VBox* newScene = new VBox(); EntityStruct* e; /* * ClearScene() is a new function in Menu to clear out the items. Cf. * the orig menu.{h,c} vs ./nmenu.{h,c}. * * NOT. Want to stick with standard version of lib. See SetScene below. * * NOT NOT. Cant get to work easily without ClearScene; too many iv lib * members are private. */ ClearScene(); /**/ if (newnames) { while (e = (EntityStruct*) newnames->Enum()) { Include(new LinkNameListMenuItem(e->GetName(), e, browser, parentname)); // newScene->Insert(new LinkNameListMenuItem(e->GetName(), e, browser)); } } /* * Replacement for ClearScene above. * SetScene(newScene); */ /* * Virtual destructors evidently dont work in g++-1.39. Fix when all is * moved to version 2+. * if (namelist) delete namelist; */ namelist = newnames; return this; } /* void NameListPulldownMenu::ClearScene() { SetScene(null); if (scene != nil) { delete scene; } scene = nil; } */ /*** * Links menu member function implementations. */ LinksMenu::LinksMenu(const char* name, RSLBrowser* browser) : PulldownMenu(name) { this->browser = browser; } LinksMenu* LinksMenu::InstallNames(EntityStructList* newnames) { VBox* newScene = new VBox(); EntityStruct* e; ClearScene(); if (newnames) { while (e = (EntityStruct*) newnames->Enum()) { LinksMenuItem* lm = new LinksMenuItem(e->GetName(), browser); if (e->GetSym()) lm->InstallNames((EntityStructList*) e->GetSym(), e->GetName()); Include(lm); } } /* * Virtual destructors evidently dont work in g++-1.39. Fix when all is * moved to version 2+. * if (namelist) delete namelist; */ namelist = newnames; return this; } NameListMenuItem::NameListMenuItem(const char* name, EntityStruct* es, RSLBrowser* browser) : MenuItem(name) { this->es = es; this->browser = browser; } void NameListMenuItem::Do() { /* if (es->GetSym()) */ browser->UpdateCurEntity(es); } LinkNameListMenuItem::LinkNameListMenuItem(const char* name, EntityStruct* es, RSLBrowser* browser, char* parentname) : NameListMenuItem(name, es, browser) { /* * A la NameListMenuItem constructor, with the addition of setting * isGraphic member based on value of parentname. Viz., if parentname * is "picture" then isGraphic is set to true, else false. */ isGraphic = streq(parentname, "picture"); } void LinkNameListMenuItem::Do() { #ifndef RBROWSEONLY if (isGraphic) GetLiveWin()->GetIdraw()->GetEditor()->FindObject(es->GetName()); else #endif browser->UpdateCurEntity(es); } CloseSubMenuMenuItem::CloseSubMenuMenuItem( const char* name, RSLBrowser* browser) : MenuItem(name) { this->name = newstr(name); this->browser = browser; } CloseSubMenuMenuItem::~CloseSubMenuMenuItem() { delete name; } ExposeSubMenuMenuItem::ExposeSubMenuMenuItem( const char* name, RSLBrowser* browser, CloseSubMenuMenuItem* sibling) : MenuItem(name) { this->name = newstr(name); this->sibling = sibling; this->browser = browser; } ExposeSubMenuMenuItem::~ExposeSubMenuMenuItem() { delete name; /* Sibling will be deleted from above. */ } const char* ExposeSubMenuMenuItem::GetName() { return name; } CloseSubMenuMenuItem* ExposeSubMenuMenuItem::GetSibling() { return sibling; } OpenMenuItem::OpenMenuItem(RSLBrowser* browser, FileDialog* dialog) : MenuItem("Open ...") { prevopenfile = "\0"; /* iv's file chooser cant hack just null */ this->browser = browser; this->dialog = dialog; } /* * dormant * CloseMenuItem::CloseMenuItem(RSLBrowser* browser, FileListDialog* dialog) : MenuItem("Close ...") { this->browser = browser; this->dialog = dialog; } ExposeMenuItem::ExposeMenuItem(RSLBrowser* browser, FileListDialog* dialog) : MenuItem("Expose =>") { this->browser = browser; this->dialog = dialog; } * */ SaveMenuItem::SaveMenuItem(RSLBrowser* browser) : MenuItem("Save") { this->browser = browser; } SaveAsMenuItem::SaveAsMenuItem(RSLBrowser* browser, FileDialog* dialog) : MenuItem("Save As ...") { prevsavedfile = "\0"; /* iv's file chooser cant hack just null */ this->browser = browser; this->dialog = dialog; } SaveAllMenuItem::SaveAllMenuItem(RSLBrowser* browser) : MenuItem("Save All") { this->browser = browser; } RescanMenuItem::RescanMenuItem(RSLBrowser* browser) : MenuItem("Rescan") { this->browser = browser; } SearchForwMenuItem::SearchForwMenuItem( RSLBrowser* browser, SearchDialog* dialog) : MenuItem("Search Forw ...") { this->browser = browser; this->dialog = dialog; } SearchBackMenuItem::SearchBackMenuItem( RSLBrowser* browser, SearchDialog* dialog) : MenuItem("Search Back ...") { this->browser = browser; this->dialog = dialog; } GotoLineMenuItem::GotoLineMenuItem( RSLBrowser* browser, SearchDialog* dialog) : MenuItem("Goto Line ...") { this->browser = browser; this->dialog = dialog; } QuitMenuItem::QuitMenuItem(RSLBrowser* browser, exception* exitExc) : MenuItem("Quit") { this->browser = browser; this->exitExc = exitExc; } TestMenuItem::TestMenuItem(RSLBrowser* browser) : MenuItem("Perform System Test") { this->browser = browser; } void OpenMenuItem::Do() { /* * Pass the buck to browser->Open() after getting the file. */ const char* filename = dialog->ChooseFile(prevopenfile); if (filename) { if (prevopenfile) delete prevopenfile; prevopenfile = newstr(filename); browser->Open(newstr(filename)); } } /* * Dormant: * void CloseMenuItem::Do() { } void ExposeMenuItem::Do() { } * */ void SaveMenuItem::Do() { /* * Save the contents of the current editor in the path associated therewith. */ /* * Dont do needless work from the menu. This check is here rather than in * Browser::Save since we may want to force saving when not in edit mode * (e.g., after Browser::Close, q.v.). */ if (not browser->InEditMode()) { browser->ErrorDialog("Nothing to save."); } else { browser->Save(); } } void SaveAsMenuItem::Do() { /* * Save the contents of the current editor in a path chosen from a file * chooser. */ if (not browser->CurEd()) { browser->ErrorDialog("No file is currently active."); return; } const char* filename = dialog->ChooseFile(prevsavedfile); if (filename) { prevsavedfile = filename; browser->SaveAs(filename); } } void SaveAllMenuItem::Do() { /* * Save the contents of the all editors in the paths associated therewith. */ /* * Dont do needless work from the menu. This check is here rather than in * Browser::Save since we may want to force rescan when not in edit mode * (e.g., after Browser::Close, q.v.). */ if (not browser->InEditMode()) { browser->ErrorDialog("Nothing to save."); } else { browser->SaveAll(); } } void SearchForwMenuItem::Do() { /* * Put up a string chooser and pass string onto the browser for the search. */ const char* s = dialog->ChooseSearchString(); if (s) browser->SearchForw(s); } void SearchBackMenuItem::Do() { /* * As search foward. */ const char* s = dialog->ChooseSearchString(); if (s) browser->SearchBack(s); } void GotoLineMenuItem::Do() { /* * Put up a string chooser convert result to int, and pass string onto the * browser for the search. */ const char* s = dialog->ChooseSearchString(); if (s) browser->GotoLine(atoi(s)); } /* * Say bye bye. */ void QuitMenuItem::Do() { browser->CheckExit(); throw(*exitExc, null); } /* * Perform some system testing function. This function is for system-level * debugging only. */ void TestMenuItem::Do() { systest(); } void RescanMenuItem::Do() { /* * Rescan the current set of input files. Since the previously current entity * may have been deleted or changed, there is no cur entity after the rescan is * completed. If the rescan results in any errors, the browser does not change * state at all. * * Re. the text ed list, it stays in tact after the rescan. */ /* * Dont do needless work from the menu. This check is here rather than in * Browser::Save since we may want to force rescan when not in edit mode * (e.g., after Browser::Close, q.v.). */ if (not browser->InEditMode()) { browser->ErrorDialog("Nothing to save."); } else { browser->Rescan(); } } void ModulesMenuItem::Do() { /* * The symtab entry of the * entity struct to which this points contains a src loc. The src loc * in turns contains the name of the file in which the selected module resides. * Display this file in the current text ed. */ char* path = es->GetSym()->Loc.file; browser->Edit(path); } void ComponentsMenuItem::Do() { /* * From here it's simple -- just pass this's EntityStruct up to the browser to * have the browser state updated. */ browser->UpdateCurEntity(es); } void ParentsMenuItem::Do() { /* * Ibid. */ browser->UpdateCurEntity(es); } void InstancesMenuItem::Do() { /* * Ibid. */ browser->UpdateCurEntity(es); } void InstanceofMenuItem::Do() { /* * Ibid. */ browser->UpdateCurEntity(es); } void OpsMenuItem::Do() { /* * Ibid. */ browser->UpdateCurEntity(es); } void InsMenuItem::Do() { /* * Ibid. */ browser->UpdateCurEntity(es); } void OutsMenuItem::Do() { /* * Ibid. */ browser->UpdateCurEntity(es); } ToggleMenuItem::ToggleMenuItem(char* str, char* state0Val, char* state1Val, bool prependVal, bool initState, RSLBrowser* browser) : MenuItem(str) { name = str; state = initState; prepend = prependVal; state0 = state0Val; state1 = state1Val; this->browser = browser; DisplayName(); } void ToggleMenuItem::Toggle() { delete fullname; state = state ? false : true; DisplayName(); } void ToggleMenuItem::DisplayName() { fullname = new char[strlen(name) + max(strlen(state0), strlen(state1)) + 2]; if (prepend) sprintf(fullname, "%s %s", state ? state0 : state1, name); else sprintf(fullname, "%s %s", name, state ? state0 : state1); Insert(new Message(fullname, Left, 2, hfil, 0)); } /* * Note subtlety here. Viz., when going from edit mode on to edit mode off, * a full rescan is performed. If the rescan fails, then we stay in edit mode, * i.e., edit mode is not turned off. We need to check for this outcome here, * and not toggle when it occurs. We do this via the Browser::RescanFailed * prediate, which state-based (sucks), but easy (OK, I'll let it go this * time).. */ void EditBrowseModeMenuItem::Do() { browser->ToggleEditBrowseMode(); if (not browser->RescanFailed()) Toggle(); } void TransientMenusMenuItem::Do() { browser->ToggleTransientMenusMode(); if (browser->ObjIsCur()) parent->ComposeTransientObjUpdates(); else if (browser->OpIsCur()) parent->ComposeTransientOpUpdates(); Toggle(); } void AutoGraphicsMenuItem::Do() { browser->ToggleAutoGraphicsMode(); Toggle(); } void RedrawMenuItem::Do() { browser->Draw(); } void CloseSubMenuMenuItem::Do() { browser->Close(name); } void ExposeSubMenuMenuItem::Do() { browser->Expose(name); } /*** * Implementations of StateVisibleMenuBar. */ ControlState* StateVisibleMenuBar::GetState() { return state; } void StateVisibleMenuBar::FixStates() { /* Screw it, just do it manually for each menubar item. */ }