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