/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #include "Command.h" #include "ListIterator.h" #include "Client.h" #include "Application.h" #include "CommandScope.h" #include "Strings.h" boolean Command::CommandClassInitialized = FALSE; Symbol Command::MsgActivate = NUL(Symbol); Symbol Command::MsgDeactivate = NUL(Symbol); Symbol Command::MsgDisassociate = NUL(Symbol); Symbol Command::MsgBeginExecuting = NUL(Symbol); Symbol Command::MsgEndExecuting = NUL(Symbol); Command::Command(const char* name, CommandScope* scope, boolean active) { ASSERT(name); // // Perform class initialization, if necessary. // if (NOT Command::CommandClassInitialized) { ASSERT(theSymbolManager); Command::MsgActivate = theSymbolManager->registerSymbol("Activate"); Command::MsgDeactivate = theSymbolManager->registerSymbol("Deactivate"); Command::MsgDisassociate = theSymbolManager->registerSymbol("Disassociate"); Command::MsgBeginExecuting = theSymbolManager->registerSymbol("BeginExecuting"); Command::MsgEndExecuting = theSymbolManager->registerSymbol("EndExecuting"); Command::CommandClassInitialized = TRUE; } // // Initialize member data. // this->name = DuplicateString(name); this->active = active; this->hasUndo = TRUE; if (scope != NUL(CommandScope*)) { this->scopeList.appendElement(scope); } } Command::~Command() { Command *c; List toRemoveAuto; int autos = this->autoActivators.getSize(); if (autos > 0) { // // Let all the commands that auto-de/activated this command know that // this command is going away. Slurp the list items out of the // autoActivators list because, so that we don't have to directly // iterate over the autoActivators list when calling removeAutoCmd() // which will change the autoActivators list. // int i; Command **cmds = new Command*[autos]; ListIterator li(this->autoActivators); for (i=0 ; c = (Command*)li.getNext() ; i++) cmds[i] = c; for (i=0 ; iremoveAutoCmd(this); delete cmds; } autos = this->activateCmds.getSize(); if (autos > 0) { // // Let all the commands that we auto de/activate know that // this command is going away. See above for algorithm. // int i; Command **cmds = new Command*[autos]; ListIterator li(this->activateCmds); for (i=0 ; c = (Command*)li.getNext() ; i++) cmds[i] = c; for (i=0 ; iremoveAutoCmd(cmds[i]); delete cmds; } autos = this->deactivateCmds.getSize(); if (autos > 0) { // // Let all the commands that we auto de/activate know that // this command is going away. See above for algorithm. // int i; Command **cmds = new Command*[autos]; ListIterator li(this->deactivateCmds); for (i=0 ; c = (Command*)li.getNext() ; i++) cmds[i] = c; for (i=0 ; iremoveAutoCmd(cmds[i]); delete cmds; } delete this->name; } boolean Command::registerClient(Client* DXinterface) { boolean result; // // Add the interface to the interface list. // ASSERT(DXinterface); if (result = this->Server::registerClient(DXinterface)) { // // Sync the interface with the current state of this command. // if (this->active) { DXinterface->notify(Command::MsgActivate); } else { DXinterface->notify(Command::MsgDeactivate); } } return result; } void Command::activate() { // // 10/11/96 Reversed these 2 lines in order to make RepeatingToggle. The // new class (subclasses from ToggleButtonInterface) and executes its associated // command whenever it's activated and getState()==TRUE. In order to do that, // the command must be active first. // this->active = TRUE; this->notifyClients(Command::MsgActivate); } void Command::deactivate(const char *reason) { // // 10/11/96 Reversed these 2 lines in order to match Command::activate(). // this->active = FALSE; this->notifyClients(Command::MsgDeactivate, NULL, reason); } boolean Command::registerScope(CommandScope* scope) { ASSERT(scope); if (this->scopeList.isMember(scope)) { return FALSE; } else { return this->scopeList.appendElement(scope); } } boolean Command::unregisterScope(CommandScope* scope) { int position; ASSERT(scope); if (position = this->scopeList.getPosition(scope)) { return this->scopeList.deleteElement(position); } else { return FALSE; } } boolean Command::execute(CommandInterface *ci) { ListIterator scopeListIterator(this->scopeList); CommandScope* scope; boolean result; // // If this command is not active, do not execute. // if (NOT this->active) { return FALSE; } // // Turn busy cursor on. // ASSERT(theApplication); theApplication->setBusyCursor(TRUE); // // Execute the command (in the subclasses). // if (this->doIt(ci)) { // // Set the "Undo" command status for each scope. // while (scope = (CommandScope*)scopeListIterator.getNext()) { // // If the "Undo" command exists within the application... // if (scope->getUndoCommand()) { // // If the command is reversible, activate the "Undo" command; // otherwise, deactivate it. // if (this->hasUndo) { scope->setLastCommand(this); scope->getUndoCommand()->activate(); } else { scope->setLastCommand(NUL(Command*)); scope->getUndoCommand()->deactivate(); } } } ListIterator list; Command *c; for (list.setList(activateCmds); c = (Command *)list.getNext(); ) c->activate(); for (list.setList(deactivateCmds); c = (Command *)list.getNext(); ) c->deactivate(); result = TRUE; } else { result = FALSE; } // // Turn the busy cursor off. // theApplication->setBusyCursor(FALSE); // // Return execution result. // return result; } boolean Command::undo() { ListIterator scopeListIterator(this->scopeList); CommandScope* scope; Command* command; boolean result; // // Undo the command (in the subclasses). // if (this->undoIt()) { while (scope = (CommandScope*)scopeListIterator.getNext()) { if (command = scope->getUndoCommand()) { command->deactivate(); } } result = TRUE; } else { result = FALSE; } // // Return execution result. // return result; } void Command::autoActivate(Command *c) { int position; this->activateCmds.insertElement((const void *)c, 1); if ((position = this->deactivateCmds.getPosition((const void*)c)) != 0) this->deactivateCmds.deleteElement(position); c->addActivator(this); } void Command::autoDeactivate(Command *c) { int position; this->deactivateCmds.insertElement((const void *)c, 1); if ((position = this->activateCmds.getPosition((const void*)c)) != 0) this->activateCmds.deleteElement(position); c->addActivator(this); } void Command::removeAutoCmd(Command *c) { int position; if ((position = this->activateCmds.getPosition((const void*)c)) != 0) this->activateCmds.deleteElement(position); if ((position = this->deactivateCmds.getPosition((const void*)c)) != 0) this->deactivateCmds.deleteElement(position); c->removeActivator(this); } void Command::addActivator(Command *c) { this->autoActivators.appendElement((const void*)c); } void Command::removeActivator(Command *c) { this->autoActivators.removeElement((const void*)c); }