/***************************************************************************** # Copyright (C) 1994-2008 by David Gordon. # All rights reserved. # # This software is part of a beta-test version of the Consed/Autofinish # package. It should not be redistributed or # used for any commercial purpose, including commercially funded # sequencing, without written permission from the author and the # University of Washington. # # This software is provided ``AS IS'' and any express or implied # warranties, including, but not limited to, the implied warranties of # merchantability and fitness for a particular purpose, are disclaimed. # In no event shall the authors or the University of Washington be # liable for any direct, indirect, incidental, special, exemplary, or # consequential damages (including, but not limited to, procurement of # substitute goods or services; loss of use, data, or profits; or # business interruption) however caused and on any theory of liability, # whether in contract, strict liability, or tort (including negligence # or otherwise) arising in any way out of the use of this software, even # if advised of the possibility of such damage. # # Building Consed from source is error prone and not simple which is # why I provide executables. Due to time limitations I cannot # provide any assistance in building Consed. Even if you do not # modify the source, you may introduce errors due to using a # different version of the compiler, a different version of motif, # different versions of other libraries than I used, etc. For this # reason, if you discover Consed bugs, I can only offer help with # those bugs if you first reproduce those bugs with an executable # provided by me--not an executable you have built. # # Modifying Consed is also difficult. Although Consed is modular, # some modules are used by many other modules. Thus making a change # in one place can have unforeseen effects on many other features. # It may takes months for you to notice these other side-effects # which may not seen connected at all. It is not feasable for me to # provide help with modifying Consed sources because of the # potentially huge amount of time involved. # #*****************************************************************************/ // // editaction.h // // The EditAction class is an abstract base class for // edit actions. By convention all derived classes' // names should begin "Edit". // // From the original design doc: // // Edit actions are classes which implement all changes in // the Contig object and its components (LocatedFragments, // etc.). They do not have any knowledge of or // responsibility for either the user actions that create // them, or the changes in appearance/representation that // they cause. // // Each possible edit action is implemented as a derived // class of EditAction. The EditAction abstract base class // has two virtual member functions, do() and undo(). The // constructor for a derived class of EditAction will // require all information needed to apply that action to // the assembly. In the process of applying itself, the // object accquires and stores in private member data any // information needed to restore the assembly to its exact // state prior to the edit being applied, assuming that no // intervening edits have been made and not undone. The // edit action does not store the state of the assembly, // only a "delta". // // Edit actions are responsible for refreshing ContigWins // and Teditors. This is because particular edits may // require other tweaks to the data members // of ContigWin/Teditor. Case in point: complementation // requires that the window be scrolled as well as refreshed. // This is done by overriding virtual functions // refreshContigWin() and refreshTeditor(). [These are optional. // The default versions just cause them to be redrawn.] // // Edit actions must be atomic i.e. they are executed or not // in their entirety. There is no member data in the ConsEd // or other object that records the "state" or completion of // an edit. It fires, is do()ne or undo()ne, completes and // is recorded in the edit history or fails and throws an // exception. // // Edit actions are created by an interface object in // response to user input. Some combination of pointing, // clicking or keystrokes is interpreted as a user command // telling consed to edit the assembly in some fashion. The // member data of the object involved is presumably enough // to provide any and all information needed to apply the // action. The constructor is called with those arguments, // and a new object of type SomeEditAction is created. A // pointer to this object is passed to the ConsEd, and the // interface object is fininshed with it. It niether knows // or cares (at this point) whether the edit action // completes or fails. // // Each call to a class' edit function must return the // information the edit object will need to undo itself. // Thus if the command were to delete a base at position n, // the return value would have to be the Ntide at that // position, which otherwise would be lost. In the case of // a change in base segment, a pointer to a (small) list of // affected base segments and their former values would be // required. // // The undo() function is implemented in precisely the same // way, except that the inverse/complementary edit function // of the affected classes are called. In the above // example, the first step would be to call the "insert base // in LocatedFragment" member function of the Contig object. // If the available calls are sufficient, there is no reason // why the affected object should know if its member // function is called as part of a do() or an undo(). // // #ifndef EDITACTION_INCLUDED #define EDITACTION_INCLUDED #include "sysdepend.h" #include "rwcstring.h" class ContigWin; class Teditor; class EditAction { public: enum { nEditAction = 0, nEditComplementContig = 1 }; int nTypeID_; public: EditAction(); ~EditAction() {} // do whatever you do, saving whatever you need to undo // it if need be virtual void doEditSpecific() = 0; virtual RWCString soGetDescriptionOfEdit() = 0; void doEdit( const bool bWriteToEditHistoryFile ); // undo whatever it was you last did. no intervening edits // that have not themselves been undone. virtual void undoEditSpecific() = 0; void undoEdit( const bool bWriteToEditHistoryFile ) { undoEditSpecific(); undoSetChangedIfNecessary(); if (bWriteToEditHistoryFile ) writeUndoEditToEditHistoryFile(); } // called by the ConsEd for all Teditors after the edit has completed. // override this if derived edit action requires something special. virtual void refreshContigWin(ContigWin*); // called by the ContigWin for all its child Teditors after the edit // has completed. // override this if derived edit action requires something special. virtual void refreshTeditor(Teditor*); // needless to say, edit actions are UNIQUE and cannot // be equal. you can do the same thing twice, but it's two // separate edit actions since the context has changed after // the first one (or you didn't really edit anything). bool operator == (const EditAction& rEdAct) const { return (this == &rEdAct); } // these must be overridden in the derived class to set the bChanged_ bit // in the appropriate fragments // if the edit action does not deal with any reads, then these should be // derived as empty functions virtual void setChangedIfNecessary() = 0; virtual void undoSetChangedIfNecessary() = 0; virtual void writeEditToEditHistoryFile() = 0; void writeUndoEditToEditHistoryFile(); }; #endif // EDITACTION_INCLUDED