1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
/* sequiny.c
* ===========================================================================
*
* PUBLIC DOMAIN NOTICE
* National Center for Biotechnology Information (NCBI)
*
* This software/database is a "United States Government Work" under the
* terms of the United States Copyright Act. It was written as part of
* the author's official duties as a United States Government employee and
* thus cannot be copyrighted. This software/database is freely available
* to the public for use. The National Library of Medicine and the U.S.
* Government do not place any restriction on its use or reproduction.
* We would, however, appreciate having the NCBI and the author cited in
* any work or product based on this material
*
* Although all reasonable efforts have been taken to ensure the accuracy
* and reliability of the software and data, the NLM and the U.S.
* Government do not and cannot warrant the performance or results that
* may be obtained by using this software or data. The NLM and the U.S.
* Government disclaim all warranties, express or implied, including
* warranties of performance, merchantability or fitness for any particular
* purpose.
*
* ===========================================================================
*
* File Name: sequiny.c
*
* Author: Jim Ostell
*
* Version Creation Date: 5/24/96
*
* $Revision: 6.1 $
*
* File Description:
* This is a companion file to sequinx.c. In order to register additional proceedures
* of your own design, to replace or supplement those intrinsic to sequin,
* we have provided sequinx.c where you can register your functions with the
* object manager. For demonstration purposes, we have included a REGISTER call
* (commented out) to functions in this file.
*
* This file contains the demonstration functions themselves, as well as extensive
* comments describing what they do. They are intended to serve as a model for what
* you might do in a file of your own design.
*
* Basically, to register a proceedure with the object manager, you call a function
* which specifies a name for the function, a string to show in a menu, an input
* data type (OBJ_ in objmgr.h), possibly a subtype, and an output type, and possibly
* a subtype, the type of function (filter, editor, etc), and a pointer to the function
* to be called. The called function always
* returns an Int2 (whose values are defined in objmgr.h as OM_MSG_RET_...) and takes
* a single Pointer as an argument. This pointer always must be cast to an OMProcControlPtr
* (objmgr.h) which contains the input arguments. It is only declared as a Pointer because
* of C typedef order limitations. We will call this function the "work" function.
*
* The work function does the real job. It looks at the contents of the data pointer,
* executes the appropriate actions and returns a completion or error code. Normally it
* will return one of:
* OM_MSG_RET_ERROR - an error occurred, presumably reported with ErrPostEx()
* OM_MSG_RET_OK - everything was ok, but this function did not do anything.
* OM_MSG_RET_DONE - everything was ok, and this function did the processing requested.
*
* When the object manager looks for a function to satisfy a request it enters a loop
* which goes through appropriate functions until the action is done. First, it goes
* through all registered functions of the requested class (editor, filter,..) in priority
* order. First it looks for a match of type, and subtype. Failing that, it looks for a
* match to type, with subtype = 0 (any). For each match, it calls the function with the
* data. If the functions returns OM_MSG_RET_ERROR, or OM_MSG_RET_OK, the object manager
* tries the next function. When a function returns OM_MSG_RET_DONE or there are no more
* matching functions, the object manager returns. This means your functions can be called
* before or after the default functions (priority), or by specifying a subtype not
* supported by a default function. You can have your function called first, check the
* data to decide if you want to handle it, return OM_MSG_RET_DONE if you do, or
* OM_MSG_RET_OK if you want the object manager to find some other function to handle it.
*
* If you wish your function to receive messages from the object manager you must also
* supply a message loop function and register it with the object manager when your
* function is first called. You must remember to unregister it when your function exits.
* If your function performs some quick computation and returns, you probably don't need
* a message loop function. If it will persist awhile (like an editor or viewer) you
* probably will. This is for cases such as 1) your function is a viewer showing Bioseq X
* 2) some other function is an editor on Bioseq X. When Bioseq X is updated in the editor
* it will send an update message to the object manager. Your function will want to receive
* this message so it can update its display from the underlying (now edited) data
* appropriately. Your message loop should return OM_MSG_RET_OK (not _DONE) so the object
* manager will continue to relay the message to all functions that want to see it.
*
*
*
* Modifications:
* --------------------------------------------------------------------------
* Date Name Description of modification
* ------- ---------- -----------------------------------------------------
*
*
* ==========================================================================
*/
#include <gather.h>
#include "sequin.h"
#include "sequiny.h"
/** prototype for message loop function **/
static Int2 LIBCALLBACK MyBioseqEditMsgFunc (OMMsgStructPtr ommsp);
Int2 LIBCALLBACK MyBioseqEditFunc (Pointer data)
{
BioseqPtr bsp;
OMProcControlPtr ompcp;
Char buf[41];
OMUserDataPtr omudp; /* user data structure used for message loop */
Uint2 userkey; /* used to track omudp uniquely */
ompcp = (OMProcControlPtr) data; /* always do this cast */
/* check that all is cool */
if (ompcp == NULL) return OM_MSG_RET_ERROR;
if (ompcp->input_itemtype != OBJ_BIOSEQ) return OM_MSG_RET_ERROR;
if (ompcp->input_data == NULL) /* no BioseqPtr yet */
{
if (! GatherDataForProc (ompcp, FALSE)) /* find it -- gather.h */
{
ErrPostEx(SEV_ERROR,0,0,"MyBioseqEditFunc: couldn't gather BioseqPtr");
return OM_MSG_RET_ERROR;
}
}
bsp = (BioseqPtr)(ompcp->input_data); /* get the pointer */
BioseqLabel(bsp, buf, 40, OM_LABEL_BOTH); /* make a text string to show */
Message(MSG_OK, "MyBioseqEditFunc called with [%s]", buf); /* show it */
/* assuming we need a message loop ************************************************/
userkey = OMGetNextUserKey (); /* get a unique key for this proc instance */
/* only necessary if the same proc could be
invoked multiple times at once */
/* attach data to the entity for this procedure */
omudp = ObjMgrAddUserData(ompcp->input_entityID, ompcp->proc->procid, OMPROC_EDIT, userkey);
omudp->userdata.ptrvalue = (Pointer)bsp; /* this could point to any data */
omudp->messagefunc = MyBioseqEditMsgFunc; /* add my message loop */
/* now we can send a message to ourselves */
/* just to prove it works. The message could just
/* as well be from another proceedure though */
ObjMgrSendMsg (OM_MSG_SELECT, ompcp->input_entityID, 0, 0);
/*** end of message loop setup ***************************************************/
/** here you would do whatever work you wanted on this entry **/
/** in this case we will just arbitrarily change the length to 10 */
bsp->length = 10; /* make the change */
/* inform any listening proceedures */
ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, ompcp->input_itemID, ompcp->input_itemtype);
/*** if we set up the message loop, we need to clean up before we leave *****/
ObjMgrFreeUserData(ompcp->input_entityID, ompcp->proc->procid, OMPROC_EDIT, userkey);
/** Now we are done. Give a Done return code *******************************/
return OM_MSG_RET_DONE;
}
/******************************************************************************************
*
* Here's the sample message loop function. It really does nothing but say hello
*
*******************************************************************************************/
static Int2 LIBCALLBACK MyBioseqEditMsgFunc (OMMsgStructPtr ommsp)
{
OMUserDataPtr omudp;
BioseqPtr bsp;
Char buf[41];
omudp = (OMUserDataPtr)(ommsp->omuserdata);
bsp = (BioseqPtr)(omudp->userdata.ptrvalue);
BioseqLabel(bsp, buf, 40, OM_LABEL_BOTH); /* make a text string to show */
switch (ommsp->message)
{
case OM_MSG_DEL:
break;
case OM_MSG_CREATE:
break;
case OM_MSG_UPDATE:
Message(MSG_OK, "Got an update message on [%s]", buf);
break;
case OM_MSG_SELECT: /* add highlight code */
Message(MSG_OK, "Got a select message on [%s]", buf);
break;
case OM_MSG_DESELECT: /* add deselect code */
break;
case OM_MSG_CACHED:
break;
case OM_MSG_UNCACHED:
break;
case OM_MSG_TO_CLIPBOARD: /* this is just because no clipboard now */
break;
default:
break;
}
return OM_MSG_RET_OK;
}
|