1 /*   $Id: viewmgr.c,v 1.38 2007/03/15 14:03:07 bollin Exp $
2 * ===========================================================================
3 *
4 *                            PUBLIC DOMAIN NOTICE
5 *            National Center for Biotechnology Information (NCBI)
6 *
7 *  This software/database is a "United States Government Work" under the
8 *  terms of the United States Copyright Act.  It was written as part of
9 *  the author's official duties as a United States Government employee and
10 *  thus cannot be copyrighted.  This software/database is freely available
11 *  to the public for use. The National Library of Medicine and the U.S.
12 *  Government do not place any restriction on its use or reproduction.
13 *  We would, however, appreciate having the NCBI and the author cited in
14 *  any work or product based on this material
15 *
16 *  Although all reasonable efforts have been taken to ensure the accuracy
17 *  and reliability of the software and data, the NLM and the U.S.
18 *  Government do not and cannot warrant the performance or results that
19 *  may be obtained by using this software or data. The NLM and the U.S.
20 *  Government disclaim all warranties, express or implied, including
21 *  warranties of performance, merchantability or fitness for any particular
22 *  purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name:  $Id: viewmgr.c,v 1.38 2007/03/15 14:03:07 bollin Exp $
27 *
28 * Author:  Lewis Geer
29 *
30 * Version Creation Date:   2/1/00
31 *
32 * $Revision: 1.38 $
33 *
34 * File Description: The ViewMgr is the part of the alignment management
35 *                   system that creates a viewable seqalign from an original
36 *                   seqalign (called a target) by applying a set of
37 *                   transforms to the target, such as show/hide rows.  The
38 *                   ViewMgr also deals with allocation/deallocation of
39 *                   the target and view seqaligns.
40 *
41 * Modifications:
42 * --------------------------------------------------------------------------
43 * $Log: viewmgr.c,v $
44 * Revision 1.38  2007/03/15 14:03:07  bollin
45 * Function needs to return a value.
46 *
47 * Revision 1.37  2006/07/13 17:06:39  bollin
48 * use Uint4 instead of Uint2 for itemID values
49 * removed unused variables
50 * resolved compiler warnings
51 *
52 * Revision 1.36  2002/05/09 15:34:51  kans
53 * commented out unneeded headers in tools library
54 *
55 * Revision 1.35  2001/01/18 22:28:06  hurwitz
56 * added fast option for ViewMgr_Update
57 *
58 * Revision 1.34  2001/01/07 08:11:13  vakatov
59 * Fixed C++ style comments to the C-style ones
60 *
61 * Revision 1.33  2001/01/06 01:09:00  lewisg
62 * get indexed begin in make multiple, copy seqaligns correctly
63 *
64 * Revision 1.32  2001/01/02 23:38:20  lewisg
65 * null target and begin pointers
66 *
67 * Revision 1.31  2000/12/29 21:10:43  lewisg
68 * bug fixes
69 *
70 * Revision 1.30  2000/08/30 13:43:11  lewisg
71 * change seqalign state when made into multiple
72 *
73 * Revision 1.29  2000/08/01 12:54:29  lewisg
74 * *** empty log message ***
75 *
76 * Revision 1.28  2000/06/20 19:35:11  hurwitz
77 * use indexed seqAlign when necessary, make multiple when redrawing
78 *
79 * Revision 1.27  2000/06/16 13:44:10  lewisg
80 * fix Int4->int fcn declaration
81 *
82 * Revision 1.26  2000/06/13 18:23:54  hurwitz
83 * made ViewMgr_MakeMultiple routine, call this on each launch of DDE rather than launch of DDV
84 *
85 * Revision 1.25  2000/06/08 20:52:42  hurwitz
86 * fixed a bug with show/hide rows
87 *
88 * Revision 1.24  2000/06/07 23:08:48  lewisg
89 * fix show/hide for large number of rows
90 *
91 * Revision 1.23  2000/05/12 16:15:26  hurwitz
92 * reverted to not doing IntersectOnMaster for DDE, now determined by call to ViewMgr_Attach
93 *
94 * Revision 1.22  2000/05/10 19:02:36  hurwitz
95 * for dde, always do IntersectOnMaster
96 *
97 * Revision 1.21  2000/04/17 21:46:55  lewisg
98 * do not do double index on viewmgr update, rename menus
99 *
100 * Revision 1.20  2000/04/10 20:33:40  lewisg
101 * fix show/hide for blast multiple, make blast multiple API generic
102 *
103 * Revision 1.19  2000/04/07 18:57:17  thiessen
104 * fix VRow2TRow
105 *
106 * Revision 1.18  2000/04/04 22:18:42  lewisg
107 * add defline to ddv, fix seq import bugs, set boundbox
108 *
109 * Revision 1.17  2000/04/04 17:51:54  lewisg
110 * fix various seq import bugs
111 *
112 * Revision 1.16  2000/03/29 23:38:06  lewisg
113 * hide/show, fixes to saving and opening
114 *
115 * Revision 1.15  2000/03/27 22:15:04  lewisg
116 * add show/hide row dialog
117 *
118 * Revision 1.14  2000/03/15 19:32:20  lewisg
119 * launch only single udv window
120 *
121 * Revision 1.13  2000/03/14 14:20:15  lewisg
122 * add extern row conversion functions
123 *
124 * Revision 1.12  2000/03/10 18:47:00  lewisg
125 * add show/hide
126 *
127 * Revision 1.11  2000/03/08 21:46:13  lewisg
128 * cn3d saves viewport, misc bugs
129 *
130 * Revision 1.10  2000/03/02 21:11:05  lewisg
131 * use bandalign for import sequence, make standalone ddv use viewmgr, make dialogs modal, send color update
132 *
133 * Revision 1.9  2000/03/01 22:53:40  lewisg
134 * import bioseq, neatlyindex, get rid of dead code
135 *
136 * Revision 1.8  2000/02/22 17:22:33  lewisg
137 * fix mac error
138 *
139 * Revision 1.7  2000/02/19 01:23:58  lewisg
140 * use ibm, add row tracking code, various bug fixes
141 *
142 * Revision 1.6  2000/02/16 16:17:34  lewisg
143 * add extra argument to AlnMgrMakeMultByIntersectOnMaster
144 *
145 * Revision 1.5  2000/02/15 23:02:46  kans
146 * return 0 instead of NULL for Int4 return value - too bad only the Mac compiler can catch this
147 *
148 * Revision 1.4  2000/02/15 22:40:57  lewisg
149 * add ability to launch udv so that it colors by row, fixes to colormgr, track rows from viewmgr, fix visual c projects
150 *
151 * Revision 1.3  2000/02/10 15:51:58  lewisg
152 * cn3d responds and send correct update messages.  many coloring bug fixes
153 *
154 * Revision 1.2  2000/02/05 19:37:45  kans
155 * fixed almost certain unintended assignment in if statement - caught by Mac compiler
156 *
157 * Revision 1.1  2000/02/05 01:32:23  lewisg
158 * add viewmgr, move place freeing is done in ddv, modify visual c++ projects
159 *
160 *
161 *
162 * ==========================================================================
163 */
164 
165 #include <viewmgr.h>
166 #include <objmgr.h>
167 #include <alignmgr.h>
168 #include <sqnutils.h>
169 /*
170 #include <ddvcolor.h>
171 #include <actutils.h>
172 */
173 
174 
175 /*****************************************************************************
176 
177 Function: ViewMgr_Find
178 
179 Purpose: Finds a seqalign by pointer inside of the ViewMgr_Global
180 
181 Parameters: salp, the seqalign
182             pGlobal, the ViewMgr_Global
183 
184 Returns: a pointer to info about the alignment
185 
186 *****************************************************************************/
187 
ViewMgr_Find(ViewMgr_Global * pGlobal,SeqAlign * salp)188 static ViewMgr_AlignInfo * ViewMgr_Find(ViewMgr_Global *pGlobal,
189                                         SeqAlign *salp)
190 {
191     ValNode *pvn;
192     ViewMgr_AlignInfo *pInfo;
193 
194 
195     if(pGlobal == NULL || salp == NULL) return NULL;
196 
197     for(pvn = pGlobal->pAlignList; pvn != NULL; pvn = pvn->next) {
198         pInfo = (ViewMgr_AlignInfo *)pvn->data.ptrvalue;
199         if(pInfo == NULL) continue;
200         if(pInfo->pView == salp) return pInfo;
201     }
202     return NULL;
203 }
204 
ViewMgr_GetInfo(SeqAlign * salp)205 static ViewMgr_AlignInfo * ViewMgr_GetInfo(SeqAlign *salp)
206 {
207     ViewMgr_Global *pGlobal;
208 
209     pGlobal = GetAppProperty("ViewMgr");
210     if(pGlobal == NULL || salp == NULL) return NULL;
211     return ViewMgr_Find(pGlobal, salp);
212 }
213 
ViewMgr_xVRow2TRow(ViewMgr_Global * pGlobal,SeqAlign * salp,Int4 VRow)214 static Int4 ViewMgr_xVRow2TRow(ViewMgr_Global *pGlobal, SeqAlign *salp,
215                                Int4 VRow)
216 {
217     ViewMgr_AlignInfo * pInfo;
218     ValNode *pvn;
219     Int4 TRow, nVRow;
220     Boolean isHidden;
221 
222     if(pGlobal == NULL || salp == NULL || VRow <= 0) return -1;
223     pInfo = ViewMgr_Find(pGlobal, salp);
224     if(pInfo == NULL) ErrorReturn(SEV_ERROR, "ViewMgr_xVRow2TRow", -1);
225 
226     for (TRow = 1, nVRow = 0; ; TRow++) {
227         isHidden = FALSE;
228         for (pvn = pInfo->pHiddenRows; pvn != NULL; pvn = pvn->next) {
229             if (pvn->data.intvalue == TRow) {
230                 isHidden = TRUE;
231                 break;
232             }
233         }
234         if (!isHidden) nVRow++;
235         if (nVRow == VRow)
236             break;
237     }
238     return TRow;
239 }
240 
241 /*****************************************************************************
242 
243 Function: ViewMgr_VRow2TRow
244 
245 Purpose: Converts a viewed row to a target row
246 
247 Parameters: salp, the seqalign
248             VRow, the row number in the viewed SeqAlign
249 
250 Returns: the row in the target SeqAlign, -1 on failure
251 
252 *****************************************************************************/
ViewMgr_VRow2TRow(SeqAlign * salp,Int4 VRow)253 NLM_EXTERN Int4 ViewMgr_VRow2TRow(SeqAlign *salp, Int4 VRow)
254 {
255     ViewMgr_Global *pGlobal;
256 
257     pGlobal = GetAppProperty("ViewMgr");
258     if (pGlobal == NULL)
259         ErrorReturn(SEV_ERROR, "ViewMgr_TRow2VRow", -1);
260     return ViewMgr_xVRow2TRow(pGlobal, salp, VRow);
261 }
262 
263 
ViewMgr_xTRow2VRow(ViewMgr_Global * pGlobal,SeqAlign * salp,Int4 TRow)264 static Int4 ViewMgr_xTRow2VRow (ViewMgr_Global *pGlobal, SeqAlign *salp,
265                                Int4 TRow)
266 {
267     ViewMgr_AlignInfo * pInfo;
268     ValNode *pvn;
269     Int4 VRow = TRow;
270 
271     if(pGlobal == NULL || salp == NULL)
272         ErrorReturn(SEV_ERROR, "ViewMgr_xTRow2VRow", -1);
273     pInfo = ViewMgr_Find(pGlobal, salp);
274     if(pInfo == NULL) return -1;
275 
276     for(pvn = pInfo->pHiddenRows; pvn != NULL; pvn = pvn->next) {
277         if(pvn->data.intvalue < TRow) VRow--;
278         if(pvn->data.intvalue == TRow) return -1;
279     }
280     return VRow;
281 }
282 
283 /*****************************************************************************
284 
285 Function: ViewMgr_TRow2VRow
286 
287 Purpose: Finds a seqalign by pointer inside of the ViewMgr_Global
288 
289 Parameters: salp, the seqalign
290             TRow, the row number in the target SeqAlign
291 
292 Returns: the row in the viewed SeqAlign, -1 on failure
293 
294 *****************************************************************************/
ViewMgr_TRow2VRow(SeqAlign * salp,Int4 TRow)295 NLM_EXTERN Int4 ViewMgr_TRow2VRow (SeqAlign *salp, Int4 TRow)
296 {
297     ViewMgr_Global *pGlobal;
298 
299     pGlobal = GetAppProperty("ViewMgr");
300     if (pGlobal == NULL)
301         ErrorReturn(SEV_ERROR, "ViewMgr_TRow2VRow", -1);
302     return ViewMgr_xTRow2VRow(pGlobal, salp, TRow);
303 }
304 
305 
306 /* frees a from/to valnode chain */
ViewMgr_ClearFromTo(ValNode * Transform)307 static void ViewMgr_ClearFromTo(ValNode *Transform)
308 {
309     ValNode *pvn;
310 
311     if(Transform == NULL) return;
312     for(pvn = (ValNode *)Transform->data.ptrvalue; pvn != NULL;
313         pvn = pvn->next) MemFree(pvn->data.ptrvalue);
314     ValNodeFree((ValNode *)Transform->data.ptrvalue);
315 }
316 
ViewMgr_ClearTrans(SeqAlign * salp)317 Int4 ViewMgr_ClearTrans(SeqAlign *salp)
318 {
319     ViewMgr_Global *pGlobal;
320     ValNode *pvn;
321     ViewMgr_AlignInfo *pInfo;
322 
323     pGlobal = GetAppProperty("ViewMgr");
324     if (pGlobal == NULL)
325         ErrorReturn(SEV_ERROR, "ViewMgr_ClearTrans", -1);
326 
327     pInfo = ViewMgr_Find(pGlobal, salp);
328     if (pInfo == NULL) ErrorReturn(SEV_ERROR, "ViewMgr_ClearTrans", -1);
329 
330     for(pvn = pInfo->pTransforms; pvn != NULL; pvn = pvn->next)
331         ViewMgr_ClearFromTo(pvn);
332 
333     ValNodeFree(pInfo->pTransforms);
334     return 1;
335 }
336 
ViewMgr_AddFromTo(ValNode * Transform,Int4 From,Int4 To)337 static void ViewMgr_AddFromTo(ValNode *Transform, Int4 From, Int4 To)
338 {
339     ValNode *pvn;
340     ViewMgr_FromTo *pFromTo;
341 
342     if(Transform == NULL) ErrorReturnVoid(SEV_ERROR, "ViewMgr_AddFromTo");
343     for(pvn = (ValNode *)Transform->data.ptrvalue; pvn != NULL;
344     pvn = pvn->next) {
345         pFromTo = pvn->data.ptrvalue;
346         if(pFromTo == NULL) continue;
347         if(pFromTo->From == From || pFromTo->To == To) return;
348     }
349 
350     pFromTo = MemNew(sizeof(ViewMgr_FromTo));
351     pFromTo->From = From;
352     pFromTo->To = To;
353 
354     pvn = (ValNode *)Transform->data.ptrvalue;
355     ValNodeAddPointer(&pvn, 0, pFromTo);
356 }
357 
358 
ViewMgr_AddTransform(SeqAlign * salp,Int4 Transform,Int4 From,Int4 To)359 Int4 ViewMgr_AddTransform(SeqAlign * salp, Int4 Transform, Int4 From, Int4 To)
360 {
361     ValNode *pvn;
362     ViewMgr_AlignInfo *pInfo;
363 
364     pInfo = ViewMgr_GetInfo(salp);
365     if (pInfo == NULL) ErrorReturn(SEV_ERROR, "ViewMgr_AddTransform", -1);
366 
367     for(pvn = pInfo->pTransforms; pvn != NULL; pvn = pvn->next)
368         if(Transform == pvn->choice) break;
369 
370     if(pvn == NULL) pvn = ValNodeAddPointer(&pInfo->pTransforms, (Nlm_Int2)Transform,
371         NULL);
372     ViewMgr_AddFromTo(pvn, From, To);
373     return 1;
374 }
375 
376 
377 /*****************************************************************************
378 
379 Function: ViewMgr_GetRow
380 
381 Purpose: Returns the row that a bioseq viewer is looking at, given the
382          viewer's unique UserKey
383 
384 Parameters: pGlobal, the ViewMgr_Global
385             UserKey, the userkey of the viewer
386 
387 Returns: the row, -1 on failure
388 
389 *****************************************************************************/
390 
ViewMgr_GetRow(DDV_ColorGlobal * pCGlobal,Uint2 UserKey)391 NLM_EXTERN Int4 ViewMgr_GetRow(DDV_ColorGlobal *pCGlobal, Uint2 UserKey)
392 {
393     ViewMgr_Global *pVGlobal;
394     ViewMgr_AlignInfo *pInfo;
395     ValNode *pvn;
396 
397     pVGlobal = GetAppProperty("ViewMgr");
398     if (pVGlobal == NULL) ErrorReturn(SEV_ERROR, "ViewMgr_GetRow", -1);
399 
400     pInfo = ViewMgr_Find(pVGlobal, (SeqAlign *)pCGlobal->pObject);
401     if(pInfo == NULL) ErrorReturn(SEV_ERROR, "ViewMgr_GetRow", -1);
402 
403     for(pvn = pInfo->pUserKey2Row; pvn != NULL; pvn = pvn->next)
404         if(UserKey == pvn->choice) return ViewMgr_xTRow2VRow(pVGlobal,
405             (SeqAlign *)pCGlobal->pObject, pvn->data.intvalue);
406     ErrorReturn(SEV_ERROR, "ViewMgr_GetRow", -1);
407 }
408 
409 /*****************************************************************************
410 
411 Function: ViewMgr_SetRow
412 
413 Purpose: Sets the row that a bioseq viewer is looking at, given the
414          viewer's unique UserKey
415 
416 Parameters: pGlobal, the DDV_ColorGlobal
417             UserKey, the userkey of the viewer
418             Row, the row the viewer is looking at
419 
420 Returns: 1 on success, 0 on failure
421 
422 *****************************************************************************/
423 
ViewMgr_SetRow(DDV_ColorGlobal * pCGlobal,Uint2 UserKey,Int4 Row)424 NLM_EXTERN Int4 ViewMgr_SetRow(DDV_ColorGlobal *pCGlobal, Uint2 UserKey,
425                                Int4 Row)
426 {
427     ViewMgr_Global *pVGlobal;
428     ViewMgr_AlignInfo *pInfo;
429 
430     pVGlobal = GetAppProperty("ViewMgr");
431     if (pVGlobal == NULL) ErrorReturn(SEV_ERROR, "ViewMgr_SetRow", -1);
432 
433     pInfo = ViewMgr_Find(pVGlobal, (SeqAlign *)pCGlobal->pObject);
434     if(pInfo == NULL) ErrorReturn(SEV_ERROR, "ViewMgr_SetRow", -1);
435 
436     ValNodeAddInt(&pInfo->pUserKey2Row, UserKey, ViewMgr_xVRow2TRow(pVGlobal,
437             (SeqAlign *)pCGlobal->pObject, Row));
438 
439     return 1;
440 }
441 
442 /*****************************************************************************
443 
444 Function: ViewMgr_FreeInfo
445 
446 Purpose: Free a ViewMgr_AlignInfo
447 
448 Parameters: pInfo, to be freed
449 
450 Returns: 1 on success
451 
452 *****************************************************************************/
453 
ViewMgr_FreeInfo(ViewMgr_AlignInfo * pInfo)454 NLM_EXTERN Int4 ViewMgr_FreeInfo(ViewMgr_AlignInfo *pInfo)
455 {
456     if(pInfo == NULL) ErrorReturn(SEV_ERROR, "ViewMgr_FreeInfo", -1);
457     SeqAlignListFree(pInfo->pTarget);
458     SeqAlignListFree(pInfo->pBegin);
459     SeqAlignListFree(pInfo->pBeginIndexed);
460     ValNodeFree(pInfo->pHiddenRows);
461     ValNodeFree(pInfo->pDeleteRows);
462     /*ViewMgr_ClearTrans(pInfo->pTransforms);*/
463     MemFree(pInfo);
464     return 1;
465 }
466 
467 
468 /*****************************************************************************
469 
470 Function: ViewMgr_RemoveSA
471 
472 Purpose: Takes the information about a seqalign out of the ViewMgr
473 
474 Parameters: salp, the seqalign to remove
475 
476 Returns: 1 on success
477 
478 *****************************************************************************/
479 
ViewMgr_RemoveSA(SeqAlign * salp)480 NLM_EXTERN Int4 ViewMgr_RemoveSA(SeqAlign *salp)
481 {
482     ViewMgr_AlignInfo *pInfo;
483     ValNode *pvn, *pvnPrevious = NULL;
484     ViewMgr_Global *pGlobal;
485 
486     pGlobal = GetAppProperty("ViewMgr");
487     if(pGlobal == NULL) return -1;
488     for(pvn = pGlobal->pAlignList; pvn != NULL; pvn = pvn->next) {
489         pInfo = (ViewMgr_AlignInfo *)pvn->data.ptrvalue;
490         if(pInfo == NULL) continue;
491         if(pInfo->pView == salp) break;
492         pvnPrevious = pvn;
493     }
494 
495     if(pvn == NULL) return -1;
496     if(pvn == pGlobal->pAlignList) {
497         ViewMgr_FreeInfo(pInfo);
498         if(pvn->next != NULL) pGlobal->pAlignList = pvn->next;
499         else pGlobal->pAlignList = NULL;
500         MemFree(pvn);
501     }
502     else {
503         pvnPrevious->next = pvn->next;
504         ViewMgr_FreeInfo(pInfo);
505         MemFree(pvn);
506     }
507     return 1;
508 }
509 
510 
511 /*****************************************************************************
512 
513 Function: ViewMgr_New
514 
515 Purpose: Creates a new View Manager global for tracking SeqAligns
516 
517 Returns: the new global
518 
519 *****************************************************************************/
520 
ViewMgr_New(void)521 NLM_EXTERN ViewMgr_Global * ViewMgr_New(void)
522 {
523     ViewMgr_Global *pGlobal;
524 
525     pGlobal = GetAppProperty("ViewMgr");
526     if (pGlobal == NULL) {
527         pGlobal = MemNew(sizeof(ViewMgr_Global));
528         if (pGlobal == NULL) return NULL;
529         SetAppProperty("ViewMgr", pGlobal);
530 
531         /* set up the registration function and get a userkey */
532         ObjMgrProcLoad(OMPROC_VIEW, "ViewMgr Register", "Media", OBJ_SEQALIGN, 0,
533             OBJ_SEQALIGN, 0, NULL, ViewMgr_RegisterFunc, 0);
534 
535         pGlobal->userkey = OMGetNextUserKey();
536     }
537     return pGlobal;
538 }
539 
540 /*****************************************************************************
541 
542 Function: ViewMgr_GetTarget
543 
544 Purpose: return the original *indexed* SeqAlign given the view seqalign
545 
546 *****************************************************************************/
ViewMgr_GetTarget(SeqAlign * salp)547 NLM_EXTERN SeqAlign * ViewMgr_GetTarget(SeqAlign *salp)
548 {
549     ViewMgr_AlignInfo *pInfo;
550 
551     pInfo = ViewMgr_GetInfo(salp);
552     if(pInfo == NULL) return NULL;
553 
554     return pInfo->pTarget;
555 }
556 
557 /*****************************************************************************
558 
559 Function: ViewMgr_GetBegin
560 
561 Purpose: return the original SeqAlign given the view seqalign
562 
563 *****************************************************************************/
ViewMgr_GetBegin(SeqAlign * salp)564 NLM_EXTERN SeqAlign * ViewMgr_GetBegin(SeqAlign *salp)
565 {
566     ViewMgr_AlignInfo *pInfo;
567 
568     pInfo = ViewMgr_GetInfo(salp);
569     if(pInfo == NULL) return NULL;
570 
571     return pInfo->pBegin;
572 }
573 
574 /*****************************************************************************
575 
576 Function: ViewMgr_SetBegin
577 
578 Purpose: make pNewBegin the original SeqAlign
579 
580 *****************************************************************************/
ViewMgr_SetBegin(SeqAlign * salp,SeqAlign * pNewBegin,Boolean Neat,Boolean Intersect)581 NLM_EXTERN SeqAlign * ViewMgr_SetBegin(SeqAlign *salp, SeqAlign *pNewBegin,
582                                        Boolean Neat, Boolean Intersect)
583 {
584     ViewMgr_AlignInfo *pInfo;
585 
586     pInfo = ViewMgr_GetInfo(salp);
587     if(pInfo == NULL) return NULL;
588     SeqAlignListFree(pInfo->pBegin);
589     pInfo->pBegin = pNewBegin;
590     pInfo->Neat = Neat;
591     pInfo->Intersect = Intersect;
592     return pInfo->pBegin;
593 }
594 
595 /*****************************************************************************
596 
597 Function: ViewMgr_GetBeginIndexed
598 
599 Purpose: return the original SeqAlign given the view seqalign.  This is
600 an indexed copy of the original SeqAlign.
601 
602 *****************************************************************************/
ViewMgr_GetBeginIndexed(SeqAlign * salp)603 NLM_EXTERN SeqAlign * ViewMgr_GetBeginIndexed(SeqAlign *salp)
604 {
605     ViewMgr_AlignInfo *pInfo;
606 
607     pInfo = ViewMgr_GetInfo(salp);
608     if(pInfo == NULL) return NULL;
609 
610     if(!pInfo->BeginIndexed) {
611         if(pInfo->Intersect) {
612             AlnMgrMakeMultByIntersectOnMaster(pInfo->pBeginIndexed, TRUE);
613         }
614         else {
615             AlnMgrIndexSeqAlign(pInfo->pBeginIndexed);
616         }
617         pInfo->BeginIndexed = TRUE;
618     }
619     return pInfo->pBeginIndexed;
620 }
621 
622 
623 /*****************************************************************************
624 
625 Function: ViewMgr_IsNeat
626 
627 Purpose: is the seqalign neatly indexed?
628 
629 *****************************************************************************/
ViewMgr_IsNeat(SeqAlign * salp)630 NLM_EXTERN Boolean ViewMgr_IsNeat(SeqAlign *salp)
631 {
632     ViewMgr_AlignInfo *pInfo;
633     pInfo = ViewMgr_GetInfo(salp);
634     if(!pInfo) return FALSE;
635 
636     if(pInfo->Neat) return TRUE;
637     return FALSE;
638 }
639 
640 
641 /*****************************************************************************
642 
643 Function: ViewMgr_IsIBM
644 
645 Purpose: is the seqalign IBMed?
646 
647 *****************************************************************************/
ViewMgr_IsIBM(SeqAlign * salp)648 NLM_EXTERN Boolean ViewMgr_IsIBM(SeqAlign *salp)
649 {
650     ViewMgr_AlignInfo *pInfo;
651     pInfo = ViewMgr_GetInfo(salp);
652     if(!pInfo) return FALSE;
653 
654     if(pInfo->Intersect) return TRUE;
655     return FALSE;
656 }
657 
658 
659 /*****************************************************************************
660 
661 Function: ViewMgr_Delete
662 
663 Purpose: Creates a new View Manager global for tracking SeqAligns
664 
665 Returns: the new global
666 
667 *****************************************************************************/
668 
ViewMgr_Delete(ViewMgr_Global * pGlobal)669 NLM_EXTERN ViewMgr_Global * ViewMgr_Delete(ViewMgr_Global *pGlobal)
670 {
671     ValNode * pvn;
672     if (pGlobal != NULL) {
673         for(pvn = pGlobal->pAlignList; pvn != NULL; pvn = pvn->next) {
674             ViewMgr_FreeInfo((ViewMgr_AlignInfo *)pvn->data.ptrvalue);
675         }
676 
677         ValNodeFree(pGlobal->pAlignList);
678         pGlobal = MemFree(pGlobal);
679     }
680     return(pGlobal);
681 }
682 
ViewMgr_Swap(SeqAlign * salp1,SeqAlign * salp2)683 static void ViewMgr_Swap(SeqAlign *salp1, SeqAlign *salp2)
684 {
685     void *pSwap;
686     Int4 lSwap;
687     GatherIndex gSwap;
688 
689     lSwap = (Int4)salp1->type;
690     salp1->type = salp2->type;
691     salp2->type = (Uint1)lSwap;
692 
693     lSwap = (Int4)salp1->segtype;
694     salp1->segtype = salp2->segtype;
695     salp2->segtype = (Uint1)lSwap;
696 
697     lSwap = (Int4)salp1->dim;
698     salp1->dim = salp2->dim;
699     salp2->dim = (Int2)lSwap;
700 
701     pSwap = (void *)salp1->score;
702     salp1->score = salp2->score;
703     salp2->score = (ScorePtr)pSwap;
704 
705     pSwap = (void *)salp1->segs;
706     salp1->segs = salp2->segs;
707     salp2->segs = pSwap;
708 
709     pSwap = (void *)salp1->next;
710     salp1->next = salp2->next;
711     salp2->next = (SeqAlign *)pSwap;
712 
713     pSwap = (void *)salp1->bounds;
714     salp1->bounds = salp2->bounds;
715     salp2->bounds = (SeqLocPtr)pSwap;
716 
717     pSwap = (void *)salp1->master;
718     salp1->master = salp2->master;
719     salp2->master = (SeqIdPtr)pSwap;
720 
721     pSwap = (void *)salp1->saip;
722     salp1->saip = salp2->saip;
723     salp2->saip = (SeqAlignIndexPtr)pSwap;
724 
725     MemCpy((void *)&gSwap, (void *)&salp1->idx, sizeof(GatherIndex));
726     MemCpy((void *)&salp1->idx, (void *)&salp2->idx, sizeof(GatherIndex));
727     MemCpy((void *)&salp2->idx, (void *)&gSwap, sizeof(GatherIndex));
728 
729     lSwap = (Int4)salp1->alignID;
730     salp1->alignID = salp2->alignID;
731     salp2->alignID = (Uint2)lSwap;
732 }
733 
ViewMgr_CmpInt(void * int1,void * int2)734 static int LIBCALLBACK ViewMgr_CmpInt(void *int1, void *int2)
735 {
736     if(int1 && int2) return *(Int4 *)int2 - *(Int4 *)int1;
737     else return 0;
738 }
739 
ViewMgr_Massage(ViewMgr_AlignInfo * pInfo)740 static Int4 ViewMgr_Massage(ViewMgr_AlignInfo *pInfo)
741 {
742     Int4 *throwaway, len, i;
743     ValNode *pvn;
744 
745     SeqAlignListFree(pInfo->pTarget);
746     pInfo->pTarget = NULL;
747     SeqAlignListFree(pInfo->pBeginIndexed);
748     pInfo->pBeginIndexed = NULL;
749     pInfo->BeginIndexed = FALSE;
750 
751     if(pInfo->Neat) {
752         if(!AlnMgrNeatlyIndex(pInfo->pBegin))
753             ErrorReturn(SEV_ERROR, "ViewMgr_Massage", -1);
754         /* delete neat rows */
755         len = ValNodeLen(pInfo->pHiddenRows);
756         pInfo->pBeginIndexed = SeqAlignListDup(pInfo->pBegin);
757         AlnMgrNeatlyIndex(pInfo->pBeginIndexed);
758         if(len > 0) {
759             throwaway = MemNew(sizeof(Int4)*len);
760             for(pvn = pInfo->pHiddenRows, i = 0; pvn != NULL; pvn = pvn->next, i++)
761                 throwaway[i] = pvn->data.intvalue;
762             pInfo->pTarget = AlnMgrTossNeatRows(pInfo->pBegin, throwaway, len);
763             MemFree(throwaway);
764         }
765         else {
766             pInfo->pTarget = SeqAlignListDup(pInfo->pBegin);
767             AlnMgrNeatlyIndex(pInfo->pTarget);
768         }
769     }
770     else {
771         pInfo->pTarget = SeqAlignListDup(pInfo->pBegin);
772         pInfo->pBeginIndexed = SeqAlignListDup(pInfo->pBegin);
773     }
774 
775     if(pInfo->Intersect) {
776         AlnMgrMakeMultByIntersectOnMaster(pInfo->pTarget, TRUE);
777     }
778     else {
779         AlnMgrIndexSeqAlign(pInfo->pTarget);
780 
781         /* delete unneat rows */
782         if(!pInfo->Neat) {
783             len = ValNodeLen(pInfo->pHiddenRows);
784             if(len > 0) {
785                 throwaway = MemNew(sizeof(Int4)*len);
786                 for(pvn = pInfo->pHiddenRows, i = 0; pvn != NULL; pvn = pvn->next, i++)
787                     throwaway[i] = pvn->data.intvalue;
788                 HeapSort(throwaway, len, sizeof(Int4), ViewMgr_CmpInt);
789                 for(i = 0; i < len; i++) {
790                     AlnMgrDeleteNthRow(pInfo->pTarget, throwaway[i]);
791                     AlnMgrReIndexSeqAlign(pInfo->pTarget);
792                 }
793                 MemFree(throwaway);
794             }
795         }
796     }
797     return 1;
798 }
799 
800 /*****************************************************************************
801 
802 Function: ViewMgr_MakeMultiple
803 
804 Purpose: Turns a pairwise seqalign into a multiple
805 
806 Parameters: salp, the seqalign to be turned into a multiple
807 
808 Returns: 1 on success, 0 otherwise
809 
810 *****************************************************************************/
811 
ViewMgr_MakeMultiple(SeqAlign * salp)812 NLM_EXTERN Int4 ViewMgr_MakeMultiple(SeqAlign *salp)
813 {
814     ViewMgr_AlignInfo *pInfo;
815     SeqAlign *pSeqAlign;
816 
817     if(salp == NULL)
818         ErrorReturn(SEV_ERROR, "ViewMgr_MakeMultiple", -1);
819     pInfo = ViewMgr_GetInfo(salp);
820     if(pInfo == NULL) ErrorReturn(SEV_ERROR, "ViewMgr_MakeMultiple", -1);
821 
822     pSeqAlign = AlnMgrGetSubAlign(ViewMgr_GetBeginIndexed(salp), NULL, 0, -1);
823 
824     if(pSeqAlign == NULL) return 0;
825     pInfo->pBegin = pSeqAlign;
826     /*    ViewMgr_Massage(pInfo); */
827 
828     /*    AlnMgrCopyIndexedParentIntoSap(pInfo->pTarget, salp); */
829 
830     return ViewMgr_Update(salp);
831 }
832 
833 
834 /*****************************************************************************
835 
836 Function: ViewMgr_Attach
837 
838 Purpose:  Adds the seqalign to the global and starts tracking it
839 
840 Parameters: salp, a seqalign that *isn't* indexed.
841             Intersect, true if intersect-on-master should be applied
842             Neat, true if AlnMgrNeatlyIndex should be applied
843             entityID, itemID of object passed in.  If entityID == 0,
844                 then salp is used to look up the values.
845 
846 Returns: 0 on error, 1 otherwise
847 
848 Notes: will index the seqalign
849 
850 *****************************************************************************/
851 
ViewMgr_Attach(SeqAlign * salp,Boolean Neat,Boolean Intersect,Uint2 entityID,Uint4 itemID)852 NLM_EXTERN Int4 ViewMgr_Attach(SeqAlign *salp, Boolean Neat,
853                                Boolean Intersect, Uint2 entityID,
854                                Uint4 itemID)
855 {
856     ViewMgr_AlignInfo *pInfo;
857     ViewMgr_Global *pGlobal;
858 
859     pGlobal = ViewMgr_New();
860     if(pGlobal == NULL || salp == NULL)
861         ErrorReturn(SEV_ERROR, "ViewMgr_Attach", -1);
862 
863     /* don't bother attaching it again */
864     if(ViewMgr_Find(pGlobal, salp) != NULL) return 1;
865 
866     if (entityID == 0) {
867         entityID = ObjMgrGetEntityIDForPointer(salp);
868         itemID =
869             GetItemIDGivenPointer(entityID, OBJ_SEQALIGN, (void *) salp);
870     }
871 
872     /* check to see if indexed, if it is, return
873     if(AlnMgrCheckAlignForParent(salp) > 0)
874         ErrorReturn(SEV_ERROR, "ViewMgr_Attach", -1);*/
875 
876     /* add a message func.  use AppProperty hack to pass values */
877     GatherSpecificProcLaunch(0, "ViewMgr Register", OMPROC_VIEW,
878         FALSE, entityID, itemID, OBJ_SEQALIGN);
879 
880     pInfo = MemNew(sizeof(ViewMgr_AlignInfo));
881     if(pInfo == NULL) ErrorReturn(SEV_ERROR, "ViewMgr_Attach", -1);
882 
883     pInfo->Neat = Neat;
884     pInfo->Intersect = Intersect;
885     pInfo->pBegin = SeqAlignListDup(salp);
886     ViewMgr_Massage(pInfo);
887 
888     AlnMgrCopyIndexedParentIntoSap(pInfo->pTarget, salp);
889 
890     pInfo->pView = salp;
891     pInfo->entityID = entityID;
892 
893     ValNodeAddPointer(&pGlobal->pAlignList, 0, pInfo);
894 
895     return 1;
896 }
897 
898 
899 /*****************************************************************************
900 
901 Function: ViewMgr_Add
902 
903 Purpose: Add a seqalign to a seqalign already in the viewmgr
904 
905 Parameters: salp, the seqalign to be added to.  Must be attached to viewmgr
906             salpAdd, the seqalign to be added.  should not be indexed.
907 
908 Returns: 1 on success
909 
910 *****************************************************************************/
911 
ViewMgr_Add(SeqAlign * salp,SeqAlign * salpAdd)912 NLM_EXTERN Int4 ViewMgr_Add(SeqAlign *salp, SeqAlign *salpAdd)
913 {
914     ViewMgr_AlignInfo *pInfo;
915     SeqAlign *pSeqAlign;
916 
917     if(salp == NULL || salpAdd == NULL)
918         ErrorReturn(SEV_ERROR, "ViewMgr_Add", -1);
919     pInfo = ViewMgr_GetInfo(salp);
920     if(pInfo == NULL) ErrorReturn(SEV_ERROR, "ViewMgr_Add", -1);
921 
922     /* check indexed state */
923 /*    if (AlnMgrCheckAlignForParent(salp) < 0 ||
924         AlnMgrCheckAlignForParent(salpAdd) >= 0)
925         ErrorReturn(SEV_ERROR, "ViewMgr_Add", -1);*/
926 
927     for(pSeqAlign = pInfo->pBegin; pSeqAlign->next != NULL;
928         pSeqAlign = pSeqAlign->next);
929 
930     pSeqAlign->next = salpAdd;
931 
932     return ViewMgr_Update(salp);
933 }
934 
935 
936 /*****************************************************************************
937 
938 Function: ViewMgr_SetHidden
939 
940 Purpose: Set a row to contribute / not contribute to the seqalign
941 
942 Parameters: salp, the seqalign to be shown/hid
943             Row, the row to show or hide
944             Hidden,
945 
946 Returns: 1 on success, 0 on setup failure, -1 if the requested action can't
947          be done.
948 
949 *****************************************************************************/
950 
ViewMgr_SetHidden(SeqAlign * salp,Boolean Hidden,Int4 Row)951 NLM_EXTERN Int4 ViewMgr_SetHidden(SeqAlign *salp, Boolean Hidden, Int4 Row)
952 {
953     ViewMgr_AlignInfo *pInfo;
954     ValNode *pvn, *pvnPrev;
955 
956     pInfo = ViewMgr_GetInfo(salp);
957     if(pInfo == NULL) return 0;
958     /* check to see if indexed */
959     if (AlnMgrCheckAlignForParent(salp) < 0) return 0;
960     if(pInfo->Intersect && !pInfo->Neat) return 0;  /* can't handle this case */
961     if (Hidden) {
962         /*	if(AlnMgrGetNumRows(pInfo->pBegin) - ValNodeLen(pInfo->pHiddenRows) < 3) return -1;  not indexed */
963         for(pvn = pInfo->pHiddenRows; pvn != NULL; pvn = pvn->next)
964             if(pvn->data.intvalue == Row) break;
965         if(pvn == NULL) {
966             ValNodeAddInt(&pInfo->pHiddenRows, (Nlm_Int2)Row, Row);
967             return 1;
968             }
969         else return -1;
970     }
971     else {
972         for(pvnPrev = pvn = pInfo->pHiddenRows; pvn != NULL; pvn = pvn->next) {
973             if(pvn->data.intvalue == Row) {
974                 if(pvnPrev == pvn) pInfo->pHiddenRows = pvn->next;
975                 else pvnPrev->next = pvn->next;
976                 MemFree(pvn);
977                 return 1;
978             }
979             else pvnPrev = pvn;
980         }
981         return -1;
982     }
983 
984     return 0;
985 }
986 
987 
ViewMgr_Update(SeqAlign * salp)988 NLM_EXTERN Int4 ViewMgr_Update(SeqAlign *salp) {
989   return ViewMgr_Update2(salp, FALSE);
990 }
991 
992 
993 /*****************************************************************************
994 
995 Function: ViewMgr_Update
996 
997 Purpose: Copies the target into the viewed seqalign, performs all the
998         transformations, then sends an update message
999 
1000 Parameters: salp, the seqalign to work on
1001 
1002 Returns: 1 on success
1003 
1004 *****************************************************************************/
ViewMgr_Update2(SeqAlign * salp,Boolean Fast)1005 NLM_EXTERN Int4 ViewMgr_Update2(SeqAlign *salp, Boolean Fast)
1006 {
1007     ViewMgr_AlignInfo *pInfo;
1008     Uint4 itemID;
1009     DDVUpdateMSG dum;
1010 
1011     pInfo = ViewMgr_GetInfo(salp);
1012     if(pInfo == NULL) return 0;
1013 
1014     ViewMgr_Massage(pInfo);
1015 
1016     AlnMgrCopyIndexedParentIntoSap(pInfo->pTarget, salp);
1017 
1018     if (!Fast) {
1019       itemID =
1020           GetItemIDGivenPointer(pInfo->entityID, OBJ_SEQALIGN, (void *) salp);
1021 
1022       /* first tell everyone to recolor the entity */
1023       MemSet(&dum, 0, sizeof(DDVUpdateMSG));
1024       dum.data = NULL;
1025       dum.type = UPDATE_TYPE_RECOLOR;
1026 
1027       ObjMgrSendProcMsg(OM_MSG_UPDATE, pInfo->entityID, itemID, OBJ_SEQALIGN,
1028 				  0, 0, (Pointer)&dum);
1029 
1030       /* then redraw the entity */
1031       MemSet(&dum, 0, sizeof(DDVUpdateMSG));
1032       dum.data = NULL;
1033       dum.type = UPDATE_TYPE_VIEWMGR;
1034 
1035       ObjMgrSendProcMsg(OM_MSG_UPDATE, pInfo->entityID, itemID, OBJ_SEQALIGN,
1036 				  0, 0, (Pointer)&dum);
1037     }
1038 
1039     return 1;
1040 }
1041 
1042 
1043 /*****************************************************************************
1044 
1045 Function: ViewMgr_MsgFunc
1046 
1047 Purpose: this listens to the entity the seqalign sits in.  If there is a
1048          request that the object be deleted and the viewmgr has the last
1049          messagefunc, the object is deleted.
1050 
1051 *****************************************************************************/
1052 
ViewMgr_MsgFunc(OMMsgStructPtr ommsp)1053 static Int2 LIBCALLBACK ViewMgr_MsgFunc(OMMsgStructPtr ommsp)
1054 {
1055     OMUserDataPtr omudp = NULL;
1056     Int4 Count = 0;
1057     OMMessageFunc messagefunc = NULL;
1058     ViewMgr_Global *pGlobal;
1059     ValNode *pvn;
1060     ViewMgr_AlignInfo *pInfo;
1061 
1062     omudp = (OMUserDataPtr) (ommsp->omuserdata);
1063 
1064     switch (ommsp->message) {
1065     case OM_MSG_UPDATE:
1066         break;
1067 
1068     case OM_MSG_DEL:
1069         /* kill the object if there are no more message funcs */
1070         for(;omudp != NULL; omudp = omudp->next) {
1071             if(omudp->messagefunc != NULL) {
1072                 Count++;
1073                 messagefunc = omudp->messagefunc;
1074             }
1075         }
1076         if(Count == 1 && messagefunc == ViewMgr_MsgFunc) {
1077             ObjMgrFreeUserData(ommsp->entityID, 0, 0, 0);  /* deadlock? */
1078             pGlobal = GetAppProperty("ViewMgr");
1079             if(pGlobal != NULL) {
1080                 for(pvn = pGlobal->pAlignList; pvn != NULL; pvn = pvn->next) {
1081                     pInfo = (ViewMgr_AlignInfo *)pvn->data.ptrvalue;
1082                     if(pInfo == NULL) continue;
1083                     if(pInfo->entityID == ommsp->entityID) {
1084                         ViewMgr_RemoveSA(pInfo->pView);
1085                         break;
1086                     }
1087                 }
1088                 if(pGlobal->pAlignList == NULL) {
1089                     ViewMgr_Delete(pGlobal);
1090                     RemoveAppProperty("ViewMgr");
1091                 }
1092             }
1093         }
1094         return OM_MSG_RET_OK;
1095         break;
1096 
1097     default:
1098         break;
1099 
1100     }
1101 return OM_MSG_RET_OK;
1102 }
1103 
1104 
1105 /*****************************************************************************
1106 
1107 Function: ViewMgr_RegisterFunc
1108 
1109 Purpose: Adds the ViewMgr message function to the seqalign
1110 
1111 *****************************************************************************/
1112 
ViewMgr_RegisterFunc(Pointer data)1113 NLM_EXTERN Int2 LIBCALLBACK ViewMgr_RegisterFunc(Pointer data)
1114 {
1115     OMProcControlPtr ompcp = NULL;
1116     OMUserDataPtr omudp = NULL;
1117     ViewMgr_Global *pGlobal;
1118 
1119     ompcp = (OMProcControlPtr) data;
1120     if (ompcp == NULL) {
1121         Message(MSG_ERROR, "ViewMgr: Data Null 1");
1122         return OM_MSG_RET_ERROR;
1123     }
1124 
1125     if(ompcp->proc == NULL) {
1126         Message(MSG_ERROR, "ViewMgr: Data Null 2");
1127         return OM_MSG_RET_ERROR;
1128     }
1129 
1130     switch (ompcp->input_itemtype) {
1131     case OBJ_SEQALIGN:
1132         break;
1133     default:
1134         return OM_MSG_RET_ERROR;
1135     }
1136 
1137     if (ompcp->input_data == NULL) {
1138         Message(MSG_ERROR, "ViewMgr: Null Data 3");
1139         return OM_MSG_RET_ERROR;
1140     }
1141     pGlobal = GetAppProperty("ViewMgr");
1142     if(pGlobal == NULL) return OM_MSG_RET_ERROR;
1143 
1144     pGlobal->procid = ompcp->proc->procid;
1145     omudp = ObjMgrAddUserData(ompcp->input_entityID, ompcp->proc->procid,
1146                               OMPROC_EDIT, pGlobal->userkey);
1147     if (omudp != NULL) {
1148         omudp->messagefunc = ViewMgr_MsgFunc;
1149     }
1150 
1151     return OM_MSG_RET_OK;
1152 }
1153 
1154