1 /*   vsm.c
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:  vsm.c
27 *
28 * Author:  Jim Ostell
29 *
30 * Version Creation Date:   11-29-94
31 *
32 * $Revision: 6.46 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date     Name        Description of modification
39 * -------  ----------  -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44 
45 #include <vsmpriv.h>
46 #include <objsub.h>
47 #include <objfdef.h>
48 #include <dlogutil.h>
49 #include <bspview.h>
50 #include <salpacc.h>
51 #include <explore.h>
52 
53 static VSMWinPtr NEAR VSMWinNew PROTO((VSeqMgrPtr vsmp));
54 
55 static void NEAR VSMWinShow PROTO((VSMWinPtr vsmwp));
56 
57 static void NEAR VSMWinDelete PROTO((VSMWinPtr vsmwp, Uint2 entityID, Uint4 itemID,
58                                           Uint2 itemtype));
59 
60 static void NEAR VSMWinRefreshData PROTO((VSMWinPtr vsmwp, Uint2 entityID,
61                                      Uint4 itemID, Uint2 itemtype));
62 
63 static void NEAR VSMPictSelect PROTO((VSMPictPtr vsmpp,
64                Uint2 entityID, Uint4 itemID, Uint2 itemtype, Boolean select));
65 
66 static VSMWinPtr NEAR VSeqMgrGetWinForW PROTO((WindoW w));
67 
68 static Boolean NEAR VSeqMgrCreateMainWindow PROTO((VSeqMgrPtr vsmp, Boolean program_window));
69 
70 static void NEAR VSeqMgrPopulateMain PROTO((VSMWinPtr vsmwp));
71 
72 #define VSM_PICT_UP_BUTTON  65001
73 #define VSM_PICT_DOWN_BUTTON 65002
74 SegmenT VSMEntityDraw PROTO((ObjMgrDataPtr omdp, VSMPictPtr vsmpp, VSeqMgrPtr vsmp));
75 
76 static OMUserDataPtr NEAR VSMAddPictureToEntity PROTO((VSMWinPtr vsmwp, Uint2 entityID, Int2 expand));
77 
78 /*****************************************************************************
79 *
80 *   VSeqMgrGenFunc()
81 *   	General function to call from ObjMgr
82 *
83 *****************************************************************************/
84 Int2 LIBCALLBACK VSeqMgrGenFunc PROTO((Pointer ompcp));
85 
86 /*****************************************************************************
87 *
88 *   VSeqMgrMsgFunc()
89 *   	function to call on each DeskTop window by the ObjMgr
90 *
91 *****************************************************************************/
92 Int2 LIBCALLBACK VSeqMgrMsgFunc PROTO((OMMsgStructPtr ommsp));
93 
94 
95 Int2 LIBCALLBACK VSMPictMsgFunc PROTO((OMMsgStructPtr ommsp));
96 
97 /*****************************************************************************
98 *
99 *   Public VSeqMgr Functions
100 *
101 *****************************************************************************/
102 
103 /*****************************************************************************
104 *
105 *   VSeqMgrInit(show)
106 *   	if (show) displays the window.
107 *   	OtherWise, just initializes.
108 *
109 *****************************************************************************/
VSeqMgrInit(Boolean show)110 Boolean LIBCALL VSeqMgrInit (Boolean show)
111 {
112 	VSeqMgrPtr vsmp;
113 
114 	if (show)
115 	{
116 		return VSeqMgrShow();
117 	}
118 
119 	vsmp = VSeqMgrGet();
120 	if (vsmp == NULL) return FALSE;
121 
122 	return TRUE;
123 }
124 
125 /*****************************************************************************
126 *
127 *   VSeqMgrShow()
128 *   	display the VSeqMgr
129 *   	initializes if not already done
130 *
131 *****************************************************************************/
VSeqMgrShow(void)132 Boolean LIBCALL VSeqMgrShow(void)
133 {
134 	VSeqMgrPtr vsmp;
135 	VSMWinPtr tmp;
136 
137         /***
138 	Message(MSG_OK, "In VSeqMgrShow");
139 	***/
140 
141 	vsmp = VSeqMgrGet();
142 	for (tmp = vsmp->wins; tmp != NULL; tmp = tmp->next)
143 	{
144 		tmp->in_process = TRUE;
145 		VSMWinRefreshData(tmp, 0,0,0);
146 		VSMWinShow(tmp);
147 	}
148 
149 	return TRUE;
150 }
151 
152 /*****************************************************************************
153 *
154 *   VSeqMgrDelete()
155 *      removes the VSeqMgr from the screen
156 *      keeps settings for the main window
157 *
158 *****************************************************************************/
VSeqMgrDelete(void)159 Boolean LIBCALL VSeqMgrDelete(void)
160 {
161 	VSeqMgrPtr vsmp;
162 	VSMWinPtr tmp, next=NULL;
163 
164 	vsmp = VSeqMgrGet();
165 	for (tmp = vsmp->wins; tmp != NULL; tmp = next)
166 	{
167 		next = tmp->next;
168 		VSMWinDelete(tmp, 0,0,0);
169 	}
170 	return TRUE;
171 }
172 
173 static char * VSeqMgrStr = "NCBIDT";
174 
175 
IsVSeqMgrOpen(void)176 NLM_EXTERN Boolean IsVSeqMgrOpen (void)
177 {
178 	VSeqMgrPtr vsmp=NULL;
179   VSMWinPtr win;
180   Boolean   any_shown = FALSE;
181 
182 	vsmp = (VSeqMgrPtr) GetAppProperty(VSeqMgrStr);
183   if (vsmp == NULL) {
184     return FALSE;
185   }
186   for (win = vsmp->wins; win != NULL && !any_shown; win = win->next) {
187     if (win->shown) {
188       any_shown = TRUE;
189     }
190   }
191   return any_shown;
192 }
193 
194 
195 /*****************************************************************************
196 *
197 *   Return the current VSeqMgr
198 *   	Initialize if not done already
199 *
200 *****************************************************************************/
VSeqMgrGet(void)201 VSeqMgrPtr LIBCALL VSeqMgrGet (void)
202 {
203 	VSeqMgrPtr vsmp=NULL;
204 
205 	vsmp = (VSeqMgrPtr) GetAppProperty(VSeqMgrStr);
206 	if (vsmp == NULL)
207 	{	                             /*** have to initialize it **/
208 		vsmp = (VSeqMgrPtr) MemNew (sizeof(VSeqMgr));
209 	                             /*** initialize the functions **/
210 		vsmp->omp = ObjMgrGet();
211 		vsmp->appname = StringSave(VSeqMgrStr);   /* used for the app file as well */
212 		SetAppProperty (VSeqMgrStr, (void *) vsmp);
213 
214 		VSeqMgrCreateMainWindow(vsmp, FALSE);
215 	}
216 
217 	return vsmp;
218 }
219 
220 /*****************************************************************************
221 *
222 *   Run VSeqMgr as the main program
223 *   	Initialize if not done already
224 *
225 *****************************************************************************/
VSeqMgrRun(CharPtr title,CharPtr aboutinfo)226 void LIBCALL VSeqMgrRun (CharPtr title, CharPtr aboutinfo)
227 {
228 	VSeqMgrPtr vsmp=NULL;
229 
230 	vsmp = (VSeqMgrPtr) GetAppProperty(VSeqMgrStr);
231 	if (vsmp == NULL)
232 	{	                             /*** have to initialize it **/
233 		vsmp = (VSeqMgrPtr) MemNew (sizeof(VSeqMgr));
234 		vsmp->aboutinfo = StringSave(aboutinfo);
235 		vsmp->title = StringSave(title);
236 	                             /*** initialize the functions **/
237 		vsmp->omp = ObjMgrGet();
238 		vsmp->appname = StringSave(VSeqMgrStr);   /* used for the app file as well */
239 		SetAppProperty (VSeqMgrStr, (void *) vsmp);
240 
241 		if (! VSeqMgrCreateMainWindow(vsmp, TRUE))
242 			return;
243 	}
244 
245 	VSeqMgrShow();
246 
247 	ProcessEvents();
248 
249 	return;
250 }
251 
QuitVSeqMgr(WindoW w)252 static void QuitVSeqMgr (WindoW w)
253 {
254 	VSMWinPtr vsmwp;
255 
256  	vsmwp = VSeqMgrGetWinForW(w);
257 	if (vsmwp->is_main_VSM)
258 		VSeqMgrDelete();
259 	else
260 		VSMWinDelete(vsmwp,0,0,0);
261 	return;
262 }
263 
ResizeVSeqMgr(WindoW w)264 static void ResizeVSeqMgr (WindoW w)
265 {
266 	VSMWinPtr vsmwp;
267 
268 	vsmwp = VSeqMgrGetWinForW(w);
269 
270 	/***
271 	Message(MSG_OK, "In Resize");
272 	***/
273 
274 	if (vsmwp != NULL)
275 	{
276 		if (vsmwp->shown && (! vsmwp->in_process))
277 		{
278 			vsmwp->in_process = TRUE;
279 			VSMWinRefreshData(vsmwp, 0,0,0);
280 			vsmwp->in_process = FALSE;
281 			/**
282 			VSMWinShow(vsmwp);
283 			**/
284 		}
285 	}
286 	return;
287 }
288 
VSMWinShow(VSMWinPtr vsmwp)289 static void NEAR VSMWinShow (VSMWinPtr vsmwp)
290 {
291 	if (vsmwp == NULL) return;
292 
293 	/***
294 	Message(MSG_OK, "In VSMWinShow");
295 	***/
296 
297 	if (! vsmwp->populated)
298 	{
299 		vsmwp->in_process = TRUE;
300 		VSMWinRefreshData(vsmwp, 0,0,0);
301 	}
302 
303     vsmwp->in_process = FALSE;
304 	if (! vsmwp->shown)
305 	{
306 		Show(vsmwp->w);
307 		vsmwp->shown = TRUE;
308 		Select(vsmwp->w);
309 	}
310 	return;
311 }
312 
VSMWinRefreshData(VSMWinPtr vsmwp,Uint2 entityID,Uint4 itemID,Uint2 itemtype)313 static void NEAR VSMWinRefreshData (VSMWinPtr vsmwp, Uint2 entityID,
314                                      Uint4 itemID, Uint2 itemtype)
315 {
316 	if (vsmwp == NULL) return;
317 
318 	/**
319 	Message(MSG_OK, "In refresh data");
320 	**/
321 	                   /* not on screen and not being prepared for screen */
322 	if (! (vsmwp->shown || vsmwp->in_process))
323 		return;
324 
325 	if (vsmwp->entityID == 0)
326 		VSeqMgrPopulateMain(vsmwp);
327 	else
328 		Message(MSG_ERROR, "Got a non-main window in refresh");
329 	return;
330 }
331 
VSeqMgrOpenMenuProc(IteM i)332 static void VSeqMgrOpenMenuProc (IteM i)
333 {
334 	Int2 retval;
335 	ObjMgrProcPtr ompp;
336 	OMProcControl ompc;
337 
338 	ompp = (ObjMgrProcPtr) GetObjectExtra(i);
339 	if (ompp == NULL || ompp->func == NULL)
340 		return;
341 
342 	MemSet(&ompc, 0, sizeof(OMProcControl));
343 	ompc.proc = ompp;
344 	retval = (*(ompp->func)) (&ompc);
345 	if (retval == OM_MSG_RET_ERROR)
346 		ErrShow();
347 	return;
348 }
349 
VSeqMgrSaveMenuProc(IteM i)350 static void VSeqMgrSaveMenuProc (IteM i)
351 {
352 	Int2 retval;
353 	ObjMgrProcPtr ompp;
354 	OMProcControl ompc;
355 
356 	ompp = (ObjMgrProcPtr) GetObjectExtra(i);
357 	if (ompp == NULL || ompp->func == NULL)
358 		return;
359 
360 	MemSet(&ompc, 0, sizeof(OMProcControl));
361 	ompc.do_not_reload_from_cache = TRUE;
362 	if (! GatherDataForProc(&ompc, TRUE))  /* anything selected? */
363 	{
364 		ErrShow();
365 		Message (MSG_ERROR, "Nothing selected");
366 		return;
367 	}
368 	ompc.proc = ompp;
369 	retval = (*(ompp->func)) (&ompc);
370 	if (retval == OM_MSG_RET_ERROR)
371 		ErrShow();
372 	return;
373 }
374 
375 
376 /*
377 static Boolean ObjMgrProcMatch (ObjMgrProcPtr ompp, OMProcControlPtr ompcp, Boolean showerror)
378 {
379 	ObjMgrTypePtr omtp1, omtp2;
380 	ObjMgrPtr omp;
381 	Boolean ok = FALSE;
382 	Uint2 subtype=0;
383 	Pointer ptr=NULL;
384 
385 	if ((ompp == NULL) || (ompcp == NULL))
386 		return FALSE;
387 
388 	if (ompp->inputtype == 0)
389 		return TRUE;
390 
391 	if (ompp->inputtype == ompcp->input_itemtype)
392 	{
393 		ok = TRUE;
394 		ptr = ompcp->input_data;
395 	}
396 	else if (ompp->inputtype == ompcp->input_choicetype)
397 	{
398 		ok = TRUE;
399 		ptr = ompcp->input_choice;
400 	}
401 
402 	if (ok)
403 	{
404 		if (ompp->subinputtype != 0)
405 		{
406 			omp = ObjMgrGet();
407 			omtp1 = ObjMgrTypeFind(omp, ompp->inputtype, NULL, NULL);
408 			if (omtp1 != NULL)
409 				subtype = (*(omtp1->subtypefunc)) (ptr);
410 			if (subtype != ompp->subinputtype)
411 			{
412 				if (showerror)
413 					ErrPostEx(SEV_ERROR,0,0,"Trying to put subtype %d into function taking subtype %d",
414 						(int)subtype, (int)(ompp->subinputtype));
415 				return FALSE;
416 			}
417 		}
418 	}
419 
420 	if (! ok)
421 	{
422 		if (showerror)
423 		{
424 			omp = ObjMgrGet();
425 			omtp1 = ObjMgrTypeFind(omp, ompp->inputtype, NULL, NULL);
426 			if (omtp1 == NULL)
427 			{
428 				ErrPostEx(SEV_ERROR,0,0,"Input type for function not registered");
429 				return FALSE;
430 			}
431 			omtp2 = ObjMgrTypeFind(omp, ompcp->input_itemtype, NULL, NULL);
432 			if (omtp2 == NULL)
433 			{
434 				ErrPostEx(SEV_ERROR,0,0,"Selected data type not registered");
435 				return FALSE;
436 			}
437 			ErrPostEx(SEV_ERROR,0,0,"Trying to put a %s into function taking a %s",
438 				omtp2->label, omtp1->label);
439 		}
440 		return FALSE;
441 	}
442 	return TRUE;
443 }
444 */
445 
ShowVSMProc(IteM i)446 static void ShowVSMProc (IteM i)
447 {
448 	VSeqMgrShow();
449 	return;
450 }
451 
452 typedef struct sbstruc {
453   CharPtr    name;
454   MenU       menu;
455 } Sbstruc, PNTR SbstrucPtr;
456 
VSeqMgrStdMenuProc(IteM i)457 static void VSeqMgrStdMenuProc (IteM i)
458 {
459 	Int2 retval;
460 	ObjMgrProcPtr ompp;
461 	OMProcControl ompc;
462 
463 	ompp = (ObjMgrProcPtr) GetObjectExtra(i);
464 	if (ompp == NULL || ompp->func == NULL)
465 		return;
466 
467 	MemSet(&ompc, 0, sizeof(OMProcControl));
468 	ompc.do_not_reload_from_cache = TRUE;
469 	GatherDataForProc(&ompc, TRUE);
470 	ompc.proc = ompp;
471 	retval = (*(ompp->func)) (&ompc);
472 	if (retval == OM_MSG_RET_ERROR)
473 		ErrShow();
474 	/*
475 	if (! GatherDataForProc(&ompc, TRUE))
476 	{
477 		ErrShow();
478 		return;
479 	}
480 
481 	if (ObjMgrProcMatch(ompp, &ompc, TRUE))
482 	{
483 		ompc.proc = ompp;
484 		retval = (*(ompp->func)) (&ompc);
485 
486 		if (retval == OM_MSG_RET_ERROR)
487 			ErrShow();
488 	}
489 	else
490 		ErrShow();
491 	*/
492 	return;
493 }
494 
495 /*****************************************************************************
496 *
497 *   VSMAddToMenu(MenU m, Int2 menutype)
498 *      Adds a VSM style submenu to Menu
499 *      All included procs must have already been registered with the
500 *        objmgr.
501 *
502 *****************************************************************************/
VSMAddToMenu(MenU m,Int2 menutype)503 Boolean LIBCALL VSMAddToMenu (MenU m, Int2 menutype)
504 {
505 	MenU s, x;
506 	ObjMgrProcPtr ompp;
507 	ObjMgrPtr omp;
508 	VSeqMgrPtr vsmp;
509 	Int2 ctr, proctype;
510 	static Int2 proctypes [3] = {
511 		0,
512 		OMPROC_OPEN,
513 		OMPROC_SAVE};
514 	static CharPtr menuname [3] = {
515 		"NCBI DeskTop",
516 		"Open",
517 		"Save As"};
518 	ValNodePtr submenulist = NULL, vnp;
519 	SbstrucPtr sbp;
520 	IteM i = NULL;
521 
522 	if (m == NULL) return FALSE;
523 
524 	if (menutype == VSM_DESKTOP)
525 	{
526     CommandItem(m, menuname[menutype], ShowVSMProc);
527     return TRUE;
528 	}
529 	else if (menutype != VSM_OPEN_MENU && menutype != VSM_SAVE_MENU)
530 	{
531 	  return FALSE;
532 	}
533 
534 	proctype = proctypes[menutype];
535 	vsmp = VSeqMgrGet();
536 	omp = vsmp->omp;
537 
538 	s = SubMenu (m, menuname[menutype]);
539 	ompp = NULL;
540 	ctr = 0;
541 	while ((ompp = ObjMgrProcFindNext(omp, proctype, 0,0, ompp)) != NULL)
542 	{
543 		x = NULL;
544 		if (! StringHasNoText (ompp->submenu)) {
545       vnp = submenulist;
546 		  while (vnp != NULL && x == NULL) {
547 				sbp = (SbstrucPtr) vnp->data.ptrvalue;
548 				if (sbp != NULL) {
549 					if (StringICmp (ompp->submenu, sbp->name) == 0) {
550 						x = sbp->menu;
551 					}
552 				}
553 				vnp = vnp->next;
554 			}
555 			if (x == NULL) {
556 				sbp = (SbstrucPtr) MemNew (sizeof (Sbstruc));
557 				if (sbp != NULL) {
558 					sbp->name = ompp->submenu;
559 					sbp->menu = SubMenu (s, sbp->name);
560 					x = sbp->menu;
561 					ValNodeAddPointer (&submenulist, 0, (VoidPtr) sbp);
562 				}
563 			}
564 		}
565 		if (x == NULL) {
566 			x = s;
567 		}
568 
569     if (menutype == VSM_OPEN_MENU)
570     {
571       i = CommandItem(x, ompp->proclabel, VSeqMgrOpenMenuProc);
572     }
573     else if (menutype == VSM_SAVE_MENU)
574     {
575 		  i = CommandItem(x, ompp->proclabel, VSeqMgrSaveMenuProc);
576     }
577 		SetObjectExtra(i, (VoidPtr)ompp, NULL);
578 		ctr++;
579 		vsmp->procmenu[proctype][ctr] = ompp->procid;
580 	}
581 	return TRUE;
582 }
583 
OkToListFeatDefInRemainingFeatures(Uint2 subtype)584 NLM_EXTERN Boolean OkToListFeatDefInRemainingFeatures (Uint2 subtype)
585 {
586   if (subtype != FEATDEF_PUB &&
587       subtype != FEATDEF_IMP &&
588       subtype != FEATDEF_Imp_CDS &&
589       subtype != FEATDEF_3clip &&
590       subtype != FEATDEF_5clip &&
591       subtype != FEATDEF_10_signal &&
592       subtype != FEATDEF_35_signal &&
593       subtype != FEATDEF_allele &&
594       subtype != FEATDEF_assembly_gap &&
595       subtype != FEATDEF_attenuator &&
596       subtype != FEATDEF_CAAT_signal &&
597       subtype != FEATDEF_conflict &&
598       subtype != FEATDEF_enhancer &&
599       subtype != FEATDEF_gap &&
600       subtype != FEATDEF_GC_signal &&
601       subtype != FEATDEF_mat_peptide &&
602       subtype != FEATDEF_misc_RNA &&
603       subtype != FEATDEF_misc_signal &&
604       subtype != FEATDEF_mutation &&
605       subtype != FEATDEF_old_sequence &&
606       subtype != FEATDEF_polyA_signal &&
607       subtype != FEATDEF_precursor_RNA &&
608       subtype != FEATDEF_promoter &&
609       subtype != FEATDEF_RBS &&
610       subtype != FEATDEF_repeat_unit &&
611       subtype != FEATDEF_satellite &&
612       subtype != FEATDEF_scRNA &&
613       subtype != FEATDEF_sig_peptide &&
614       subtype != FEATDEF_site_ref &&
615       subtype != FEATDEF_snoRNA &&
616       subtype != FEATDEF_snRNA &&
617       subtype != FEATDEF_source &&
618       subtype != FEATDEF_TATA_signal &&
619       subtype != FEATDEF_terminator &&
620       subtype != FEATDEF_transit_peptide &&
621       subtype != FEATDEF_virion
622       && !IsRegulatorySubtype(subtype)) {
623     return TRUE;
624   } else {
625     return FALSE;
626   }
627 }
628 
629 /*****************************************************************************
630 *
631 *   VSMAddMenu(WindoW w, Int2 menutype)
632 *      Adds a VSM style menu to Window
633 *      All included procs must have already been registered with the
634 *        objmgr.
635 *      If no procs of this type are registered, does not add to window
636 *
637 *****************************************************************************/
VSMAddMenu(WindoW w,Int2 menutype)638 Boolean LIBCALL VSMAddMenu (WindoW w, Int2 menutype)
639 {
640 	MenU m, sub, sub2, x;
641 	ObjMgrProcPtr ompp;
642 	ObjMgrPtr omp;
643 	ObjMgrTypePtr omtp;
644 	VSeqMgrPtr vsmp;
645 	Int2 ctr, proctype;
646 	FeatDispGroupPtr fdgp;
647 	FeatDefPtr fdp;
648 	Uint1 key;
649 	CharPtr label;
650 	static Int2 proctypes [5] = {
651 		0,
652 		OMPROC_FILTER ,
653 		OMPROC_ANALYZE ,
654 		OMPROC_VIEW ,
655 		OMPROC_EDIT } ;
656 	static CharPtr menuname [5] = {
657 		NULL,
658 		"Filter",
659 		"Analysis",
660 		"View",
661 		"Editor" };
662 	IteM i;
663 	ValNodePtr submenulist = NULL, vnp;
664 	SbstrucPtr sbp;
665 	Uint2 subtype;
666 
667 #ifndef WIN_MAC
668 	if (w == NULL) return FALSE;
669 #endif
670 	switch (menutype)
671 	{
672 		case VSM_FILTER_MENU:
673 		case VSM_ANALYZE_MENU:
674 		case VSM_VIEW_MENU:
675 			proctype = proctypes[menutype];
676 			vsmp = VSeqMgrGet();
677 			omp = vsmp->omp;
678 
679 			ompp = ObjMgrProcFindNext(omp, proctype, 0,0, NULL);
680 			if (ompp == NULL)   /* none registered */
681 				return FALSE;
682 
683 			m = PulldownMenu(w, menuname[menutype]);
684 			ctr = 0;
685 			do
686 			{
687 				x = NULL;
688 				if (! StringHasNoText (ompp->submenu)) {
689 					vnp = submenulist;
690 					while (vnp != NULL && x == NULL) {
691 						sbp = (SbstrucPtr) vnp->data.ptrvalue;
692 						if (sbp != NULL) {
693 							if (StringICmp (ompp->submenu, sbp->name) == 0) {
694 								x = sbp->menu;
695 							}
696 						}
697 						vnp = vnp->next;
698 					}
699 					if (x == NULL) {
700 						sbp = (SbstrucPtr) MemNew (sizeof (Sbstruc));
701 						if (sbp != NULL) {
702 							sbp->name = ompp->submenu;
703 							sbp->menu = SubMenu (m, sbp->name);
704 							x = sbp->menu;
705 							ValNodeAddPointer (&submenulist, 0, (VoidPtr) sbp);
706 						}
707 					}
708 				}
709 				if (x == NULL) {
710 					x = m;
711 				}
712 				i = CommandItem(x, ompp->proclabel, VSeqMgrStdMenuProc);
713 				SetObjectExtra(i, (VoidPtr)ompp, NULL);
714 				ctr++;
715 			}
716 			while ((ompp = ObjMgrProcFindNext(omp, proctype, 0,0, ompp)) != NULL);
717 			ValNodeFree (submenulist);
718 			return TRUE;
719 		case VSM_EDIT_MENU:
720 			proctype = proctypes[menutype];
721 			vsmp = VSeqMgrGet();
722 			omp = vsmp->omp;
723 
724 			ompp = ObjMgrProcFindNext(omp, proctype, 0,0, NULL);
725 			if (ompp == NULL)   /* none registered */
726 				return FALSE;
727 
728 			m = PulldownMenu(w, menuname[menutype]);
729 			/* code is below this switch statement */
730 			break;
731 		default:
732 			return FALSE;
733 	}
734 	omtp = NULL;
735 	ctr = 0;
736 	while ((omtp = ObjMgrTypeFindNext(omp, omtp)) != NULL) {
737 		ompp = ObjMgrProcFindNext(omp, proctype, omtp->datatype, 0, NULL);
738 		if (ompp != NULL) {
739 			if (omtp->datatype == OBJ_SEQFEAT) {
740 				sub = SubMenu (m, omtp->label);
741 				fdgp = NULL;
742 				while ((fdgp = DispGroupFindNext (fdgp, &key, &label)) != NULL) {
743 					if (fdgp->groupkey != 0) {
744 						sub2 = SubMenu (sub, fdgp->groupname);
745 						fdp = NULL;
746 						label = NULL;
747 						while ((fdp = FeatDefFindNext (fdp, &key, &label, fdgp->groupkey, FALSE)) != NULL) {
748 							if (key != FEATDEF_BAD) {
749 								ompp = NULL;
750 								while ((ompp = ObjMgrProcFindNext(omp, proctype,
751 								   	    omtp->datatype, 0, ompp)) != NULL) {
752 									if (ompp->subinputtype == fdp->featdef_key) {
753 										i = CommandItem(sub2, ompp->proclabel, VSeqMgrStdMenuProc);
754 										SetObjectExtra(i, (VoidPtr)ompp, NULL);
755 										ctr++;
756 									}
757 								}
758 							}
759 						}
760 					}
761 				}
762         sub2 = SubMenu (sub, "Remaining Features");
763         fdp = NULL;
764         while ((fdp = FeatDefFindNext (fdp, &key, &label, 0, FALSE)) != NULL) {
765           if (key != FEATDEF_BAD) {
766             ompp = NULL;
767             while ((ompp = ObjMgrProcFindNext (omp, proctype,
768 				                                        omtp->datatype, 0, ompp)) != NULL) {
769 				      subtype = ompp->subinputtype;
770               if (subtype == fdp->featdef_key && OkToListFeatDefInRemainingFeatures (subtype)) {
771                 i = CommandItem (sub2, ompp->proclabel, VSeqMgrStdMenuProc);
772                 SetObjectExtra(i, (VoidPtr)ompp, NULL);
773                 ctr++;
774               }
775             }
776           }
777         }
778 			} else {
779 				sub = SubMenu (m, omtp->label);
780 				do
781 				{
782 					i = CommandItem(sub, ompp->proclabel, VSeqMgrStdMenuProc);
783 					SetObjectExtra(i, (VoidPtr)ompp, NULL);
784 					ctr++;
785 				}
786 				while ((ompp = ObjMgrProcFindNext(omp, proctype,
787 				       omtp->datatype, 0, ompp)) != NULL);
788 			}
789 		}
790 	}
791 	return TRUE;
792 }
793 
VSeqMgrQuitProc(IteM i)794 static void VSeqMgrQuitProc (IteM i)
795 {
796 	VSeqMgrDelete();
797 	return;
798 }
799 
VSeqMgrEditProc(IteM i)800 static void VSeqMgrEditProc (IteM i)
801 {
802 	Message(MSG_OK, "Edit");
803 	return;
804 }
805 
VSeqMgrCutProc(IteM i)806 static void VSeqMgrCutProc (IteM i)
807 {
808 	OMProcControl ompc;
809 
810 	MemSet(&ompc, 0, sizeof(OMProcControl));
811 	ompc.do_not_reload_from_cache = TRUE;
812 	if (! DetachDataForProc(&ompc, TRUE))  /* anything selected? */
813 	{
814 		ErrShow();
815 		return;
816 	}
817 
818 	if (! ompc.whole_entity)   /* just a part gone, so need an update */
819 		ObjMgrSendMsg(OM_MSG_DEL, ompc.input_entityID, ompc.input_itemID, ompc.input_itemtype);
820 
821 	if (! ObjMgrAddToClipBoard (0, ompc.input_data))
822 		ErrShow();
823 
824 	return;
825 }
826 
VSeqMgrCopyProc(IteM i)827 static void VSeqMgrCopyProc (IteM i)
828 {
829 	OMProcControl ompc;
830 
831 	MemSet(&ompc, 0, sizeof(OMProcControl));
832 	ompc.do_not_reload_from_cache = TRUE;
833 	if (! CopyDataForProc(&ompc, TRUE))  /* anything selected? */
834 	{
835 		ErrShow();
836 		return;
837 	}
838 
839 	if (ompc.output_data == NULL)
840 	{
841 		ErrShow();
842 		return;
843 	}
844 
845 	if (! ObjMgrAddToClipBoard (0, ompc.output_data))
846 		ErrShow();
847 
848 	return;
849 }
850 
VSeqMgrPasteProc(IteM i)851 static void VSeqMgrPasteProc (IteM i)
852 {
853 	OMProcControl ompc;
854 	ObjMgrDataPtr omdp;
855 	ObjMgrTypePtr omtp;
856 	SelStructPtr ssp;
857 	ObjMgrPtr omp;
858 	Uint2 type;
859 	Pointer ptr;
860 
861 	omdp = ObjMgrGetClipBoard();
862 	if (omdp == NULL)
863 	{
864 		Message(MSG_ERROR, "No data in clipboard");
865 		return;
866 	}
867 
868 	MemSet(&ompc, 0, sizeof(OMProcControl));
869 	ompc.input_data = omdp->dataptr;
870 	ompc.input_entityID = omdp->EntityID;
871 	ompc.input_choice = omdp->choice;
872 	ompc.input_itemtype = omdp->datatype;
873 	ompc.input_itemID = 1;
874 	ompc.input_choicetype = omdp->choicetype;
875 	ompc.whole_entity = TRUE;
876 	ompc.do_not_reload_from_cache = TRUE;
877 
878 	if (! CopyDataForProc(&ompc, FALSE))  /* just do the copy */
879 	{
880 		ErrShow();
881 		return;
882 	}
883 
884 	if (ompc.output_data == NULL)
885 	{
886 		ErrShow();
887 		return;
888 	}
889 
890 	ompc.input_data = NULL;
891 	ompc.input_entityID = 0;
892 	ompc.input_choice = NULL;
893 	ompc.input_itemtype = 0;
894 	ompc.input_choicetype = 0;
895 	ompc.whole_entity = FALSE;
896 	ompc.do_not_reload_from_cache = TRUE;
897 
898 	ssp = ObjMgrGetSelected();
899 	if (ssp == NULL)    /* nothing selected, paste into main window */
900 	{
901 		ObjMgrRegister(ompc.output_itemtype, ompc.output_data);
902 		return;
903 	}
904 
905 	if (! AttachDataForProc(&ompc, TRUE))
906 	{
907 		ErrShow();
908 		if (ompc.output_choice != NULL)
909 		{
910 			ptr = ompc.output_choice;
911 			type = ompc.output_choicetype;
912 		}
913 		else
914 		{
915 			ptr = ompc.output_data;
916 			type = ompc.output_itemtype;
917 		}
918 		omp = ObjMgrGet();
919 		omtp = ObjMgrTypeFind(omp, type,NULL,NULL);
920 		if (omtp != NULL)
921 			(*(omtp->freefunc))(ptr);
922 	}
923 	else
924 		ObjMgrSendMsg(OM_MSG_UPDATE, ompc.input_entityID, ompc.input_itemID, ompc.input_itemtype);
925 
926 
927 
928 	return;
929 }
930 
VSeqMgrMoveProc(IteM i)931 static void VSeqMgrMoveProc (IteM i)
932 {
933 	OMProcControl ompc;
934 	ObjMgrDataPtr omdp;
935 	ObjMgrTypePtr omtp;
936 	SelStructPtr ssp;
937 	ObjMgrPtr omp;
938 	Uint2 type;
939 	Pointer ptr;
940 
941 	omdp = ObjMgrGetClipBoard();
942 	if (omdp == NULL)
943 	{
944 		Message(MSG_ERROR, "No data in clipboard");
945 		return;
946 	}
947 
948 	MemSet(&ompc, 0, sizeof(OMProcControl));
949 	ompc.output_data = omdp->dataptr;
950 	ompc.output_entityID = omdp->EntityID;
951 	ompc.output_choice = omdp->choice;
952 	ompc.output_itemtype = omdp->datatype;
953 	ompc.output_choicetype = omdp->choicetype;
954 	ompc.whole_entity = TRUE;
955 	ompc.do_not_reload_from_cache = TRUE;
956 
957 	ssp = ObjMgrGetSelected();
958 	if (ssp == NULL)    /* nothing selected, paste into main window */
959 	{
960 		ObjMgrRegister(ompc.output_itemtype, ompc.output_data);
961 		return;
962 	}
963 
964 	if (! AttachDataForProc(&ompc, TRUE))
965 	{
966 		ErrShow();
967 		if (ompc.output_choice != NULL)
968 		{
969 			ptr = ompc.output_choice;
970 			type = ompc.output_choicetype;
971 		}
972 		else
973 		{
974 			ptr = ompc.output_data;
975 			type = ompc.output_itemtype;
976 		}
977 		omp = ObjMgrGet();
978 		omtp = ObjMgrTypeFind(omp, type,NULL,NULL);
979 		if (omtp != NULL)
980 			(*(omtp->freefunc))(ptr);
981 	}
982 	else
983 		ObjMgrSendMsg(OM_MSG_UPDATE, ompc.input_entityID, ompc.input_itemID, ompc.input_itemtype);
984 
985 
986 	return;
987 }
988 
989 typedef struct warnifalignmentdata {
990 	Boolean found;
991 	SeqEntryPtr lookingfor;
992 } WarnIfAlignmentData, PNTR WarnIfAlignmentPtr;
993 
IsSeqEntryInAlignment(SeqAlignPtr salp,SeqEntryPtr sep)994 static Boolean IsSeqEntryInAlignment (SeqAlignPtr salp, SeqEntryPtr sep)
995 {
996 	BioseqPtr bsp;
997 	BioseqSetPtr bssp;
998 	SeqIdPtr sip;
999 	Boolean found = FALSE;
1000 	SeqEntryPtr this_sep;
1001 
1002 	if (IS_Bioseq (sep)) {
1003 		bsp = (BioseqPtr) sep->data.ptrvalue;
1004 		for (sip = bsp->id; sip != NULL && ! found; sip = sip->next) {
1005 			found = SeqAlignFindSeqId (salp, sip);
1006 		}
1007 	} else if (IS_Bioseq_set (sep)) {
1008 		bssp = (BioseqSetPtr) sep->data.ptrvalue;
1009 		for (this_sep = bssp->seq_set;
1010 			 this_sep != NULL && !found;
1011 			 this_sep = this_sep->next) {
1012             found = IsSeqEntryInAlignment (salp, this_sep);
1013 	    }
1014 	}
1015     return found;
1016 }
1017 
FindAlignmentCallback(SeqAnnotPtr sap,Pointer userdata)1018 static void FindAlignmentCallback (SeqAnnotPtr sap, Pointer userdata)
1019 {
1020   WarnIfAlignmentPtr wiap;
1021 	SeqAlignPtr        salp;
1022 
1023 	if (sap == NULL || sap->type != 2 || userdata == NULL) {
1024 		return;
1025 	}
1026 	wiap = (WarnIfAlignmentPtr) userdata;
1027 	if (wiap->found) return;
1028   salp = (SeqAlignPtr) sap->data;
1029 	if (salp == NULL) return;
1030 	wiap->found = IsSeqEntryInAlignment (salp, wiap->lookingfor);
1031 }
1032 
1033 
RemoveSeqEntryFromAlignments(SeqEntryPtr topsep,SeqEntryPtr sep)1034 static void RemoveSeqEntryFromAlignments (SeqEntryPtr topsep, SeqEntryPtr sep)
1035 {
1036 	BioseqPtr bsp;
1037 	BioseqSetPtr bssp;
1038 	Boolean found = FALSE;
1039 	SeqEntryPtr this_sep;
1040 
1041 	if (IS_Bioseq (sep)) {
1042 		bsp = (BioseqPtr) sep->data.ptrvalue;
1043     RemoveSequenceFromAlignments (topsep, bsp->id);
1044 	} else if (IS_Bioseq_set (sep)) {
1045 		bssp = (BioseqSetPtr) sep->data.ptrvalue;
1046 		for (this_sep = bssp->seq_set;
1047 			this_sep != NULL && !found;
1048 			this_sep = this_sep->next) {
1049       RemoveSeqEntryFromAlignments (topsep, this_sep);
1050 	  }
1051 	}
1052 }
1053 
1054 
WarnIfAlignment(Uint2 type,Pointer ptr,Uint2 input_entityID)1055 static void WarnIfAlignment (Uint2 type, Pointer ptr, Uint2 input_entityID)
1056 {
1057 	SeqEntryPtr sep;
1058 	SeqEntryPtr topsep;
1059 	WarnIfAlignmentData wiad;
1060 
1061 	if (type == 1) {
1062         sep = (SeqEntryPtr) ptr;
1063 	} else {
1064 		return;
1065 	}
1066 	topsep = GetTopSeqEntryForEntityID (input_entityID);
1067 	wiad.found = FALSE;
1068 	wiad.lookingfor = sep;
1069 
1070 	VisitAnnotsInSep (topsep, &wiad, FindAlignmentCallback);
1071 	if (wiad.found) {
1072 	  if (ANS_YES == Message (MSG_YN, "This sequence is part of an alignment.  Would you like to remove it from the alignment?")) {
1073       RemoveSeqEntryFromAlignments (topsep, sep);
1074     }
1075 	}
1076 }
1077 
VSeqMgrDeleteProc(IteM i)1078 static void VSeqMgrDeleteProc (IteM i)
1079 {
1080 	OMProcControl ompc;
1081 	ObjMgrTypePtr omtp;
1082 	ObjMgrPtr omp;
1083 	Uint2 type;
1084 	Pointer ptr;
1085 
1086 	MemSet(&ompc, 0, sizeof(OMProcControl));
1087 	ompc.do_not_reload_from_cache = TRUE;
1088 	if (! DetachDataForProc(&ompc, TRUE))  /* anything selected? */
1089 	{
1090 		ErrShow();
1091 		return;
1092 	}
1093 
1094 	if (ompc.input_choicetype)
1095 	{
1096 		type = ompc.input_choicetype;
1097 		ptr = ompc.input_choice;
1098 	}
1099 	else
1100 	{
1101 		type = ompc.input_itemtype;
1102 		ptr = ompc.input_data;
1103 	}
1104 	WarnIfAlignment (type, ptr, ompc.input_entityID);
1105 
1106 	omp = ObjMgrGet();
1107 	omtp = ObjMgrTypeFind(omp, type, NULL, NULL);
1108 	if (omtp == NULL)
1109 	{
1110 		Message(MSG_ERROR, "Delete: type [%d] not registered", (int)type);
1111 		return;
1112 	}
1113 
1114 	(*(omtp->freefunc))(ptr);
1115 
1116 	if (! ompc.whole_entity)   /* just a part gone, so need an update */
1117 		ObjMgrSendMsg(OM_MSG_DEL, ompc.input_entityID, ompc.input_itemID, ompc.input_itemtype);
1118 
1119 	return;
1120 }
1121 
VSMDragAndDrop(VSMWinPtr vsmwp,Uint2 entityID,Uint4 itemID,Uint2 itemtype)1122 static void VSMDragAndDrop(VSMWinPtr vsmwp, Uint2 entityID, Uint4 itemID, Uint2 itemtype)
1123 {
1124 	OMProcControl ompc;
1125 
1126 	MemSet(&ompc, 0, sizeof(OMProcControl));
1127 	ompc.input_entityID = vsmwp->entityID1;
1128 	ompc.input_itemID = vsmwp->itemID1;
1129 	ompc.input_itemtype = vsmwp->itemtype1;
1130  	ompc.do_not_reload_from_cache = TRUE;
1131 
1132 
1133 	if (! DetachDataForProc(&ompc, FALSE))
1134 	{
1135 		ErrShow();
1136 		return;
1137 	}
1138 
1139 	if (ompc.input_choicetype)
1140 	{
1141 	    WarnIfAlignment (ompc.input_choicetype, ompc.input_choice, ompc.input_entityID);
1142 	}
1143 	else
1144 	{
1145 	    WarnIfAlignment (ompc.input_itemtype, ompc.input_data, ompc.input_entityID);
1146 	}
1147 
1148 	if (! ompc.whole_entity)   /* just a part gone, so need an update */
1149 		ObjMgrSendMsg(OM_MSG_DEL, ompc.input_entityID, ompc.input_itemID, ompc.input_itemtype);
1150 
1151 	if (entityID == 0)   /* going into desktop */
1152 	{
1153 		ObjMgrSendMsg(OM_MSG_UPDATE, ompc.input_entityID, ompc.input_itemID, ompc.input_itemtype);
1154 		ObjMgrRegister(ompc.input_itemtype, ompc.input_data);
1155 		AssignIDsInEntityEx (entityID, ompc.input_itemtype, ompc.input_data, NULL);
1156 		return;
1157 	}
1158 
1159 	ompc.output_entityID = ompc.input_entityID;
1160 	ompc.output_itemID = ompc.input_itemID;
1161 	ompc.output_itemtype = ompc.input_itemtype;
1162 	ompc.output_choice = ompc.input_choice;
1163 	ompc.output_data = ompc.input_data;
1164 	ompc.output_choicetype = ompc.input_choicetype;
1165 	ompc.whole_entity = FALSE;
1166 	ompc.input_entityID = entityID;
1167 	ompc.input_itemID = itemID;
1168 	ompc.input_itemtype = itemtype;
1169 	ompc.input_choicetype = 0;
1170 	ompc.input_choice = NULL;
1171 	ompc.input_data = NULL;
1172  	ompc.do_not_reload_from_cache = TRUE;
1173 
1174 	if (! AttachDataForProc(&ompc, FALSE))
1175 	{
1176 		ErrShow();      /* put in desktop */
1177 		ObjMgrRegister(ompc.output_itemtype, ompc.output_data);
1178 	}
1179 	else
1180 		ObjMgrSendMsg(OM_MSG_UPDATE, ompc.input_entityID, ompc.input_itemID, ompc.input_itemtype);
1181 
1182 	return;
1183 
1184 }
1185 
VSMMarquee(VSMWinPtr vsmwp)1186 static void VSMMarquee( VSMWinPtr vsmwp )
1187 {
1188 	RecT dr;
1189 
1190 	WidePen(4);
1191 	InvertMode();
1192 	Dotted();
1193 	SectRect(&(vsmwp->r), &(vsmwp->rv), &dr);
1194 	FrameRect(&dr);
1195 	return;
1196 }
1197 
VSeqMgrClickProc(VieweR v,SegmenT s,PoinT p)1198 static void VSeqMgrClickProc (VieweR v, SegmenT s, PoinT p)
1199 {
1200 	VSMWinPtr vsmwp;
1201 	SegmenT sp, top, prev, next;
1202 	Uint2 segID, primID, primCt;
1203 	BoxInfo box;
1204 	PntInfo pi;
1205 	PoinT tl, br;
1206 
1207 	vsmwp = (VSMWinPtr)GetViewerData(v);
1208 	if (vsmwp == NULL)
1209 	{
1210 		Message(MSG_ERROR, "vsmwp was NULL in ClickProc");
1211 		return;
1212 	}
1213 
1214 	vsmwp->dblclick = dblClick;
1215 	vsmwp->shftkey = shftKey;
1216 	vsmwp->dragged = FALSE;
1217 	if (dblClick)
1218 	{
1219 		if (vsmwp->marquee)
1220 		{
1221 			VSMMarquee(vsmwp);
1222 			vsmwp->marquee = FALSE;
1223 		}
1224 		return;
1225 	}
1226 
1227 	sp = FindSegment(v, p, &segID, &primID, &primCt);
1228 	if (sp == NULL)
1229 	{
1230 		if (vsmwp->marquee)
1231 		{
1232 			VSMMarquee(vsmwp);
1233 			vsmwp->marquee = FALSE;
1234 		}
1235 		return;
1236 	}
1237 
1238 	SegmentBox(sp, &box);
1239 	pi.x = box.left;
1240 	pi.y = box.top;
1241 	MapWorldToViewer(v, pi, &tl);
1242 	pi.x = box.right;
1243 	pi.y = box.bottom;
1244 	MapWorldToViewer(v, pi, &br);
1245 	LoadRect(&(vsmwp->r), tl.x, tl.y, br.x, br.y);
1246 	LoadPt (&(vsmwp->lastpnt), p.x, p.y);
1247 	vsmwp->marquee = TRUE;
1248 	VSMMarquee(vsmwp);
1249 
1250 	vsmwp->itemtype1 = segID;
1251 	vsmwp->itemID1 = primID;
1252 	top = sp;
1253 	prev = sp;
1254 	while ((next = ParentSegment(top)) != NULL)
1255 	{
1256 		prev = top;
1257 		top = next;
1258 	}
1259 	vsmwp->entityID1 = (Uint2)SegmentID(prev);
1260 
1261 	return;
1262 }
1263 
VSeqMgrReleaseProc(VieweR v,SegmenT s,PoinT p)1264 static void VSeqMgrReleaseProc (VieweR v, SegmenT s, PoinT p)
1265 {
1266 	VSMWinPtr vsmwp;
1267 	SegmenT sp, top, next, prev;
1268 	Uint2 segID, primID, primCt, entityID=0, itemtype = 0;
1269 	Uint4 itemID = 0;
1270 	Int2 expand = 0;
1271 	Boolean do_drag = FALSE;
1272 	SeqViewProcsPtr  svpp;
1273 	Int2  handled;
1274 
1275 	vsmwp = (VSMWinPtr)GetViewerData(v);
1276 	if (vsmwp == NULL)
1277 	{
1278 		Message(MSG_ERROR, "vsmwp was NULL in ReleaseProc");
1279 		return;
1280 	}
1281 
1282 	if (vsmwp->marquee)
1283 	{
1284 		VSMMarquee(vsmwp);
1285 		vsmwp->marquee = FALSE;
1286 	}
1287 
1288 	sp = FindSegment(v, p, &segID, &primID, &primCt);
1289 	if (sp == NULL)
1290 	{
1291 		if (! vsmwp->dragged)
1292 			ObjMgrDeSelectAll();
1293 		else
1294 			do_drag = TRUE;
1295 	}
1296 	else
1297 	{
1298 		itemtype = segID;
1299 		itemID = primID;
1300 		top = sp;
1301 		prev = sp;
1302 		while ((next = ParentSegment(top)) != NULL)
1303 		{
1304 			prev = top;
1305 			top = next;
1306 		}
1307 		entityID = (Uint2)SegmentID(prev);
1308        /***
1309 		Message(MSG_OK, "Calling ObjMgrSelect(%ld, %ld, %ld)",
1310 			(long)entityID, (long)itemID, (long)itemtype);
1311 		***/
1312 
1313         if (vsmwp->dblclick) {
1314           svpp = (SeqViewProcsPtr) GetAppProperty ("SeqDisplayForm");
1315           if (svpp != NULL) {
1316             if (svpp->launchEditors) {
1317               WatchCursor ();
1318               Update ();
1319               handled = GatherProcLaunch (OMPROC_EDIT, FALSE, entityID, itemID,
1320                                           itemtype, 0, 0, itemtype, 0);
1321               ArrowCursor ();
1322               Update ();
1323               if (handled == OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
1324                 return;
1325               }
1326             }
1327           }
1328           return;
1329         } else if ((! vsmwp->dragged) ||
1330         	((entityID == vsmwp->entityID1) &&
1331         	 (itemID == vsmwp->itemID1) &&
1332         	 (itemtype == vsmwp->itemtype1)))
1333         {
1334         	if (itemID == VSM_PICT_UP_BUTTON)
1335         		expand = 1;
1336         	else if (itemID == VSM_PICT_DOWN_BUTTON)
1337         		expand = -1;
1338 
1339         	if (! expand) {
1340         		if (vsmwp->shftkey) {
1341 					ObjMgrAlsoSelect(entityID, itemID, itemtype,0,NULL);
1342         		} else {
1343 					ObjMgrSelect(entityID, itemID, itemtype,0,NULL);
1344 				}
1345 			}
1346 			else
1347 			{
1348 				WatchCursor();
1349 				VSMAddPictureToEntity(vsmwp, entityID, expand);
1350 				VSMWinRefreshData(vsmwp, entityID, 0, 0);
1351 				ArrowCursor();
1352 			}
1353 			return;
1354 		}
1355 		else
1356 			do_drag = TRUE;
1357 	}
1358 
1359 	if (do_drag)
1360 		VSMDragAndDrop(vsmwp, entityID, itemID, itemtype);
1361 
1362 	return;
1363 }
1364 
VSeqMgrDragProc(VieweR v,SegmenT s,PoinT p)1365 static void VSeqMgrDragProc (VieweR v, SegmenT s, PoinT p)
1366 {
1367 	VSMWinPtr vsmwp;
1368 
1369 	vsmwp = (VSMWinPtr)GetViewerData(v);
1370 	if (vsmwp == NULL)
1371 	{
1372 		Message(MSG_ERROR, "vsmwp was NULL in DragProc");
1373 		return;
1374 	}
1375 
1376 	if (vsmwp->marquee)
1377 	{
1378 		vsmwp->dragged = TRUE;
1379 		VSMMarquee(vsmwp);
1380 		OffsetRect(&(vsmwp->r), p.x - vsmwp->lastpnt.x, p.y - vsmwp->lastpnt.y);
1381 		VSMMarquee(vsmwp);
1382 		LoadPt(&(vsmwp->lastpnt), p.x, p.y);
1383 	}
1384 
1385 	return;
1386 }
1387 
VSMCenterLine(Nlm_RectPtr rptr,Nlm_CharPtr text,Nlm_FonT fnt)1388 static void VSMCenterLine (Nlm_RectPtr rptr, Nlm_CharPtr text, Nlm_FonT fnt)
1389 {
1390   if (fnt != NULL) {
1391     Nlm_SelectFont (fnt);
1392   }
1393   rptr->bottom = rptr->top + Nlm_LineHeight ();
1394   Nlm_DrawString (rptr, text, 'c', FALSE);
1395   rptr->top = rptr->bottom;
1396 }
1397 
VSMDrawAbout(Nlm_PaneL p)1398 static void VSMDrawAbout (Nlm_PaneL p)
1399 
1400 {
1401   Nlm_RecT  r;
1402 	VSeqMgrPtr vsmp;
1403 	CharPtr ptr, tmp;
1404 	Char last = 'x';
1405 	FonT f1, f2;
1406 	Int2 bottom;
1407 
1408 #ifdef WIN_MAC
1409 	f1 = ParseFont("Monaco,12");
1410 	f2 = ParseFont("Monaco,9");
1411 #else
1412 #ifdef WIN_MOTIF
1413 	f1 = ParseFont("Times,12");
1414 	f2 = ParseFont("Times,9");
1415 #else
1416 	f1 = ParseFont("Times New Roman,12");
1417 	f2 = ParseFont("Times New Roman,9");
1418 #endif
1419 #endif
1420 	vsmp = VSeqMgrGet();
1421   Nlm_ObjectRect (p, &r);
1422   Nlm_InsetRect (&r, 4, 4);
1423   bottom = r.bottom;
1424   Nlm_Blue ();
1425   VSMCenterLine (&r, "The NCBI DeskTop v1.0", f1);
1426   VSMCenterLine (&r, "by James M. Ostell", f2);
1427   VSMCenterLine (&r, "National Center for Biotechnology Information", f2);
1428   VSMCenterLine (&r, "National Institutes of Health, Bethesda, MD USA", f2);
1429   VSMCenterLine (&r, "(301) 496-2475  info@ncbi.nlm.nih.gov", f2);
1430 
1431   Nlm_Red();
1432 
1433   SelectFont(f2);
1434   r.top += LineHeight();
1435 
1436     if (vsmp->title != NULL)
1437     	VSMCenterLine(&r, vsmp->title, f1);
1438 	if (vsmp->aboutinfo != NULL)
1439 	{
1440 		ptr = vsmp->aboutinfo;
1441 		tmp = ptr;
1442 		while ((*ptr != '\0') && (r.top <= bottom))
1443 		{
1444 			while ((*tmp != '\0') && (*tmp != '~'))
1445 				tmp++;
1446 			last = *tmp;
1447 			*tmp = '\0';
1448 			VSMCenterLine(&r, ptr, f2);
1449 			*tmp = last;
1450 			tmp++;
1451 			ptr = tmp;
1452 		}
1453 	}
1454 	return;
1455 }
1456 
QuitVSMAbout(WindoW w)1457 static void QuitVSMAbout (WindoW w)
1458 {
1459 	Remove(w);
1460 	return;
1461 }
1462 
VSMAboutProc(IteM i)1463 static void VSMAboutProc (IteM i)
1464 {
1465 	WindoW w;
1466 	PaneL p;
1467 
1468 	w = FixedWindow (-50, -33, -10, -10, "About NCBI DeskTop", QuitVSMAbout);
1469 	p = SimplePanel (w, 28 * stdCharWidth, 12 * stdLineHeight, VSMDrawAbout);
1470 	Show (w);
1471 
1472 	return;
1473 }
1474 
QuitVSM(WindoW w)1475 static void QuitVSM (WindoW w)
1476 {
1477 	QuitProgram();
1478 	return;
1479 }
1480 
VSMQuitProc(IteM i)1481 static void VSMQuitProc (IteM i)
1482 {
1483 	QuitProgram();
1484 	return;
1485 }
1486 
VSMSetUpMenus(WindoW w,Boolean progwindow)1487 static void VSMSetUpMenus (WindoW w, Boolean progwindow)
1488 {
1489 	MenU m;
1490 
1491 	if (progwindow)
1492 	{
1493 #ifdef WIN_MAC
1494 		m = AppleMenu (NULL);
1495 		CommandItem (m, "About...", VSMAboutProc);
1496 		SeparatorItem (m);
1497 		DeskAccGroup (m);
1498 #endif
1499 		m = PulldownMenu (w, "File");
1500 #ifndef WIN_MAC
1501 		CommandItem (m, "About...", VSMAboutProc);
1502 		SeparatorItem (m);
1503 #endif
1504 	}
1505 	else
1506 	{
1507 		m = PulldownMenu (w, "File");
1508 	}
1509 
1510 	VSMAddToMenu(m, VSM_OPEN_MENU);
1511 	VSMAddToMenu(m, VSM_SAVE_MENU);
1512 
1513 	if (progwindow)
1514 		CommandItem(m, "Quit/Q", VSMQuitProc);
1515 	else
1516 		CommandItem(m, "Quit/Q", VSeqMgrQuitProc);
1517 
1518 	m = PulldownMenu (w, "Edit");
1519 	CommandItem(m, "Edit/E", VSeqMgrEditProc);
1520 	CommandItem(m, "Cut/T", VSeqMgrCutProc);
1521 	CommandItem(m, "Copy/C", VSeqMgrCopyProc);
1522 	CommandItem(m, "Paste/P", VSeqMgrPasteProc);
1523 	CommandItem(m, "Move/M", VSeqMgrMoveProc);
1524 	CommandItem(m, "Delete/D", VSeqMgrDeleteProc);
1525 	VSMAddMenu(w, VSM_FILTER_MENU);
1526 	VSMAddMenu(w, VSM_ANALYZE_MENU);
1527 
1528 	return;
1529 }
1530 
1531 /*****************************************************************************
1532 *
1533 *   VSeqMgrCreateMainWindow()
1534 *
1535 *****************************************************************************/
1536 typedef struct vsmform {
1537   FORM_MESSAGE_BLOCK
1538 } VSMForm, PNTR VSMFormPtr;
1539 
VSMFormMessage(ForM f,Int2 mssg)1540 static void VSMFormMessage (ForM f, Int2 mssg)
1541 
1542 {
1543   VSMFormPtr  vfp;
1544 
1545   vfp = (VSMFormPtr) GetObjectExtra (f);
1546   if (vfp != NULL) {
1547     switch (mssg) {
1548       case VIB_MSG_CLOSE :
1549         QuitVSeqMgr ((WindoW) f);
1550         break;
1551       default :
1552         if (vfp->appmessage != NULL) {
1553           vfp->appmessage (f, mssg);
1554         }
1555         break;
1556     }
1557   }
1558 }
1559 
VSeqMgrCreateMainWindow(VSeqMgrPtr vsmp,Boolean progwindow)1560 static Boolean NEAR VSeqMgrCreateMainWindow(VSeqMgrPtr vsmp, Boolean progwindow)
1561 {
1562 	VSMWinPtr vsmwp;
1563 	OMUserDataPtr omudp;
1564 	WindoW w;
1565 	VieweR v;
1566 	RecT rw, rv;
1567 	FonT f;
1568 	Char fontbuf[80];
1569 	ObjMgrPtr omp;
1570 	static CharPtr dttitle = "NCBI DeskTop";
1571 	CharPtr title;
1572 	VSMFormPtr vfp;
1573 	Int2 pixheight, pixwidth;
1574 	StdEditorProcsPtr sepp;
1575 	TextViewProcsPtr tvpp;
1576 
1577 	ProcessUpdatesFirst(FALSE);
1578 
1579 	WatchCursor();
1580 	if (vsmp->title != NULL)
1581 		title = vsmp->title;
1582 	else
1583 		title = dttitle;
1584 	w = NULL;
1585 	if (progwindow)
1586 	{
1587 		WatchCursor ();
1588 		ErrSetFatalLevel (SEV_MAX);
1589 
1590 		if (! SeqEntryLoad())
1591 		{
1592 			Message(MSG_ERROR, "SeqEntryLoadFailed");
1593 			ErrShow();
1594 			ArrowCursor();
1595 			return FALSE;
1596 		}
1597 		if (! SubmitAsnLoad())
1598 		{
1599 			Message(MSG_ERROR, "SubmitAsnLoadLoadFailed");
1600 			ErrShow();
1601 			ArrowCursor();
1602 			return FALSE;
1603 		}
1604 
1605 			    /* initialize File I/O procs for VSM (vsmfile.h) */
1606                 /* could also add to your menu with VSMAddToMenu() (vsm.h) */
1607 		VSMFileInit();
1608 #ifdef WIN_MAC
1609 			VSMSetUpMenus (NULL, progwindow);
1610 #endif
1611 		w = DocumentWindow (-50, -33, -10, -10, title, QuitVSM, ResizeVSeqMgr);
1612 #ifndef WIN_MAC
1613 			VSMSetUpMenus (w, progwindow);
1614 #endif
1615 	}
1616 	else
1617 	{
1618 		w = DocumentWindow (-50, -33, -10, -10, title, QuitVSeqMgr, ResizeVSeqMgr);
1619 		VSMSetUpMenus (w, progwindow);
1620 	}
1621 	pixwidth = 300;
1622 	pixheight = 300;
1623 	if (w != NULL) {
1624 		vfp = (VSMFormPtr) MemNew (sizeof (VSMForm));
1625 		if (vfp != NULL) {
1626 			SetObjectExtra (w, vfp, StdCleanupFormProc);
1627 			vfp->form = (ForM) w;
1628 			vfp->formmessage = VSMFormMessage;
1629 			sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
1630 			if (sepp != NULL) {
1631 				SetActivate (w, sepp->activateForm);
1632 				vfp->appmessage = sepp->handleMessages;
1633 			}
1634 		}
1635 	}
1636 
1637 	omp = vsmp->omp;
1638 
1639 	tvpp = (TextViewProcsPtr) GetAppProperty ("TextDisplayForm");
1640 	if (tvpp != NULL) {
1641 		pixwidth = MAX (pixwidth, tvpp->minPixelWidth);
1642 		pixheight = MAX (pixheight, tvpp->minPixelHeight);
1643 	}
1644 
1645     v = CreateViewer(w, pixwidth, pixheight, TRUE, TRUE);
1646     RealizeWindow(w);
1647     ObjectRect(w, &rw);   /* calculate realation between window and viewer */
1648     ObjectRect(v, &rv);
1649     vsmp->xoff = rv.left;
1650     vsmp->yoff = rv.top;
1651     vsmp->x = (rw.right - rw.left + 1) - (rv.right - rv.left + 1) - rv.left
1652     	 - vScrollBarWidth;
1653     vsmp->y = (rw.bottom - rw.top + 1) - (rv.bottom - rv.top + 1) - rv.top
1654     	 - hScrollBarHeight;
1655 	GetAppParam(vsmp->appname, "DeskTop", "FONT", "Times,10", fontbuf, 80);
1656 	f = ParseFont(fontbuf);
1657 	SetWindowExtra(w, (Pointer)v, NULL);
1658 	vsmp->font = f;
1659 	SelectFont(f);
1660 	vsmp->lineheight = LineHeight();
1661 	vsmp->leading = Leading();
1662 	vsmp->charw = MaxCharWidth();
1663 	vsmp->set_atp = AsnFind("Bioseq-set.class");
1664 	vsmp->procid = ObjMgrProcLoad(OMPROC_EDIT, "NCBI DeskTop", "NCBI DeskTop",
1665 		0, 0, 0,0,(Pointer)vsmp, VSeqMgrGenFunc, PROC_PRIORITY_HIGHEST);
1666 	vsmp->proctype = OMPROC_EDIT;
1667 
1668 	vsmwp = VSMWinNew(vsmp);
1669 	vsmwp->w = w;
1670 	InsetRect(&rv, 2,2);  /* allow space when clipping marquee */
1671 	LoadRect(&(vsmwp->rv), rv.left, rv.top, rv.right, rv.bottom);
1672 
1673 	omudp = ObjMgrAddUserData(0, vsmp->procid, OMPROC_EDIT, vsmwp->userkey);
1674 	omudp->userdata.ptrvalue = (Pointer)vsmwp;
1675 	omudp->messagefunc = VSeqMgrMsgFunc;
1676 	vsmwp->msgfunc = VSeqMgrMsgFunc;
1677 
1678 	ArrowCursor();
1679 	return TRUE;
1680 }
1681 
1682 /*****************************************************************************
1683 *
1684 *   VSeqMgrPopulateMain(vsmwp)
1685 *
1686 *****************************************************************************/
get_viewer_position(VieweR viewer,Int4Ptr x,Int4Ptr y)1687 static void get_viewer_position (VieweR viewer, Int4Ptr x, Int4Ptr y)
1688 
1689 {
1690   Int4 scale_x, scale_y;
1691   BoxInfo port, world;
1692   RecT v_iew;
1693 
1694   ViewerBox (viewer, &world, &port, &v_iew, &scale_x, &scale_y);
1695   *x = (port.left + port.right) / 2;
1696   *y = (port.top + port.bottom) / 2;
1697 }
1698 
VSeqMgrPopulateMain(VSMWinPtr vsmwp)1699 static void NEAR VSeqMgrPopulateMain(VSMWinPtr vsmwp)
1700 {
1701 	VieweR v = NULL;
1702 	RecT rw, rv;
1703 	BoxInfo box;
1704 	SegmenT picture, seg;
1705 	Int2 lineheight,right_frame;
1706   Uint4 i, currnum;
1707 	Int4 x, y, top,width, bigtop, diffx, diffy;
1708 	ObjMgrDataPtr omdp, PNTR omdpp;
1709 	ObjMgrPtr omp;
1710 	AsnTypePtr atp;
1711 	WindoW w;
1712 	VSeqMgrPtr vsmp;
1713 	PrimitivE p;
1714 	OMUserDataPtr omudp;
1715 	VSMPictPtr vsmpp;
1716 	Boolean doit;
1717 	Int4 vwr_x, vwr_y, vwr_align;
1718 
1719     /***
1720 	Message(MSG_OK, "In VSeqMgrPopulateMain");
1721     ***/
1722 
1723 
1724 	if (vsmwp == NULL) return;
1725 	vsmp = (VSeqMgrPtr)(vsmwp->vsmp);
1726 	w = vsmwp->w;
1727 
1728 	if (vsmp->set_atp == NULL)
1729 		vsmp->set_atp = AsnFind("Bioseq-set.class");
1730     atp = vsmp->set_atp;
1731 
1732     ObjectRect(w, &rw);
1733 
1734     LoadRect(&rv, vsmp->xoff, vsmp->yoff, rw.right - rw.left - vsmp->x,
1735     	rw.bottom - rw.top - vsmp->y);
1736 
1737     v = (VieweR) GetWindowExtra(w);
1738     vwr_x = INT4_MIN;
1739     vwr_y = INT4_MAX;
1740     vwr_align = UPPER_LEFT;
1741     if (v != NULL && vsmwp->picture != NULL) {
1742       get_viewer_position (v, &(vwr_x), &(vwr_y));
1743       vwr_align = MIDDLE_CENTER;
1744     }
1745     ResetViewer(v);
1746     SetPosition(v, &rv);
1747 	LoadRect(&(vsmwp->rv), rv.left, rv.top, rv.right, rv.bottom);
1748 	InsetRect(&(vsmwp->rv), 2,2);  /* allow space when clipping marquee */
1749 
1750 	right_frame = rv.right - rv.left + 1;
1751 
1752 	if (vsmwp->picture == NULL)
1753 		vsmwp->picture = CreatePicture();
1754 	else
1755 	{
1756 		while ((p = GetPrimitive(vsmwp->picture, 1)) != NULL)
1757 		{
1758 			UnlinkSegment((SegmenT)p);
1759 		}
1760 	}
1761 
1762 	picture = vsmwp->picture;
1763 	lineheight = vsmp->lineheight;
1764 
1765 	omp = vsmp->omp;
1766 	currnum = omp->currobj;
1767 	omdpp = omp->datalist;
1768 	x = 0;
1769 	y = 0;
1770 	bigtop = 0;
1771 	for (i = 0; i < currnum; i++, omdpp++)
1772 	{
1773 		omdp = *omdpp;
1774 		if ((omdp->parentptr == NULL) && (omdp->EntityID != 0))
1775 		{
1776 			doit = TRUE;
1777 			if ((! vsmp->show_cached) && (omdp->tempload == TL_CACHED))
1778 				doit = FALSE;
1779 			if ((! vsmp->show_clipboard) && (omdp->clipboard))
1780 				doit = FALSE;
1781 
1782 			if (doit)
1783 			{
1784 				omudp = ObjMgrGetUserData (omdp->EntityID, vsmwp->procid,
1785 									vsmwp->proctype, vsmwp->userkey);
1786 				if ((omudp == NULL) || (vsmp->update_all))  /* don't have one, or doing all */
1787 					omudp = VSMAddPictureToEntity(vsmwp, omdp->EntityID, 0);
1788 				vsmpp = (VSMPictPtr)(omudp->userdata.ptrvalue);
1789 				seg = vsmpp->s;
1790 				if ((seg != NULL) && (! vsmpp->deleted))
1791 				{
1792 					SegmentBox(seg, &box);
1793 					width = box.right - box.left + 1;
1794 					if ((x + width) > right_frame)
1795 					{
1796 						x = 0;
1797 						y = bigtop - lineheight;
1798 					}
1799 
1800 					diffx = x - box.left;
1801 					diffy = y - box.top;
1802 
1803 					OffsetSegment(seg, diffx, diffy);
1804 
1805 					top = y - (box.top - box.bottom + 1) - lineheight;
1806 					if (top < bigtop)
1807 						bigtop = top;
1808 
1809 					LinkSegment(picture, seg);
1810 
1811 					x += (width + lineheight);
1812                 }
1813 			}
1814 		}
1815 	}
1816 
1817 	vsmwp->populated = TRUE;
1818 	AttachPicture (v, picture, vwr_x, vwr_y, vwr_align, 1, 1, NULL);
1819 	SetViewerProcs(v, VSeqMgrClickProc, VSeqMgrDragProc, VSeqMgrReleaseProc, NULL);
1820 	SetViewerData(v, (Pointer)vsmwp, NULL);
1821 	if (Visible(w))
1822 		vsmwp->shown = TRUE;   /* attach picture will show it */
1823 	else
1824 		vsmwp->shown = FALSE;
1825     return;
1826 
1827 }
1828 
1829 /*****************************************************************************
1830 *
1831 *   VSMWinNew(vsmp)
1832 *   	adds a VSMWin to the chain
1833 *   	if first one, labels as is_main_VSM
1834 *
1835 *****************************************************************************/
VSMWinNew(VSeqMgrPtr vsmp)1836 static VSMWinPtr NEAR VSMWinNew (VSeqMgrPtr vsmp)
1837 {
1838 	VSMWinPtr vsmwp=NULL, tmp;
1839 
1840 	vsmwp = MemNew(sizeof(VSMWin));
1841 	vsmwp->vsmp = (Pointer)vsmp;
1842 
1843 	if (vsmp->wins == NULL)
1844 	{
1845 		vsmp->wins = vsmwp;
1846 		vsmwp->is_main_VSM = TRUE;
1847 	}
1848 	else
1849 	{
1850 		for (tmp = vsmp->wins; tmp->next != NULL; tmp = tmp->next)
1851 			continue;
1852 		tmp->next = vsmwp;
1853 	}
1854 	vsmwp->userkey = (++(vsmp->highest_userkey));
1855 	vsmwp->procid = vsmp->procid;
1856 	vsmwp->proctype = vsmp->proctype;
1857 	return vsmwp;
1858 }
1859 
1860 /*****************************************************************************
1861 *
1862 *   VSMWinDelete(vsmwp, entityID, itemID, itemtype)
1863 *   	deletes vsmwp from chain
1864 *
1865 *****************************************************************************/
VSMWinDelete(VSMWinPtr vsmwp,Uint2 entityID,Uint4 itemID,Uint2 itemtype)1866 static void NEAR VSMWinDelete(VSMWinPtr vsmwp, Uint2 entityID, Uint4 itemID, Uint2 itemtype)
1867 {
1868 	VSeqMgrPtr vsmp;
1869 	VSMWinPtr tmp, prev=NULL, next=NULL;
1870 	VieweR v;
1871 	ObjMgrDataPtr omdp, PNTR omdpp;
1872 	ObjMgrPtr omp;
1873 	Uint4 i, currnum;
1874 
1875 	if (vsmwp == NULL) return;
1876 
1877 	vsmp = VSeqMgrGet();
1878 	omp = vsmp->omp;
1879 	omdpp = omp->datalist;
1880 	currnum = omp->currobj;
1881 
1882 	if (vsmwp->entityID == 0)
1883 	{
1884 		for (i = 0; i < currnum; i++, omdpp++)
1885 		{
1886 			omdp = *omdpp;
1887 			if (omdp->EntityID)
1888 				ObjMgrFreeUserData(omdp->EntityID, vsmwp->procid, vsmwp->proctype, vsmwp->userkey);
1889 		}
1890 	}
1891 
1892 	ObjMgrFreeUserData(entityID, vsmwp->procid, vsmwp->proctype, vsmwp->userkey);
1893 
1894 	if (vsmwp->is_main_VSM)   /* don't really delete */
1895 	{                         /* if entityID != 0, could do a better refresh */
1896 		v = (VieweR)GetWindowExtra(vsmwp->w);
1897 		ResetViewer(v);
1898 		Hide(vsmwp->w);
1899 		vsmwp->picture = DeletePicture(vsmwp->picture);
1900 
1901 		vsmwp->in_process = FALSE;
1902 		vsmwp->populated = FALSE;
1903 		vsmwp->shown = FALSE;
1904 		return;
1905 	}
1906 
1907 	                          /* really delete */
1908 	Remove(vsmwp->w);
1909 
1910 	for (tmp = vsmp->wins; tmp != NULL; tmp = next)
1911 	{
1912 		next = tmp->next;
1913 		if (tmp == vsmwp)
1914 		{
1915 			if (prev == NULL)
1916 				vsmp->wins = next;
1917 			else
1918 				prev->next = next;
1919 			MemFree(tmp);
1920 			return;
1921 		}
1922 	}
1923 
1924 	return;
1925 }
1926 
1927 /*****************************************************************************
1928 *
1929 *   VSeqMgrGetWinForW(w)
1930 *   	finds the VSMWinPtr for w
1931 *   	if w==NULL, finds the main_VSM VSMWinPtr
1932 *
1933 *****************************************************************************/
VSeqMgrGetWinForW(WindoW w)1934 static VSMWinPtr NEAR VSeqMgrGetWinForW(WindoW w)
1935 {
1936 	VSeqMgrPtr vsmp;
1937 	VSMWinPtr tmp;
1938 
1939 	vsmp = VSeqMgrGet();
1940 	for (tmp = vsmp->wins; tmp != NULL; tmp = tmp->next)
1941 	{
1942 		if (w == NULL)
1943 		{
1944 			if (tmp->is_main_VSM)
1945 				return tmp;
1946 		}
1947 		else
1948 		{
1949 			if (tmp->w == w)
1950 				return tmp;
1951 		}
1952 	}
1953 
1954 	return tmp;
1955 }
1956 
1957 /*****************************************************************************
1958 *
1959 *   VSeqMgrGenFunc()
1960 *   	General function to call from ObjMgr
1961 *
1962 *****************************************************************************/
VSeqMgrGenFunc(Pointer ptr)1963 Int2 LIBCALLBACK VSeqMgrGenFunc (Pointer ptr)
1964 {
1965 	VSeqMgrPtr vsmp;
1966 	OMProcControlPtr ompcp;
1967 	VSMWinPtr vsmwp;
1968 
1969 	ompcp = (OMProcControlPtr)ptr;
1970 	vsmp = (VSeqMgrPtr)(ompcp->proc->procdata);
1971 	vsmwp = VSMWinNew(vsmp);
1972 	vsmwp->entityID = ompcp->input_entityID;
1973 	vsmwp->itemID = ompcp->input_itemID;
1974 	vsmwp->itemtype = ompcp->input_itemtype;
1975 
1976 	        /* make the picture and the window */
1977 
1978 	return OM_MSG_RET_DONE;
1979 }
1980 
1981 /*****************************************************************************
1982 *
1983 *   VSeqMgrMsgFunc()
1984 *   	function to call on each DeskTop window by the ObjMgr
1985 *
1986 *****************************************************************************/
VSeqMgrMsgFunc(OMMsgStructPtr ommsp)1987 Int2 LIBCALLBACK VSeqMgrMsgFunc (OMMsgStructPtr ommsp)
1988 {
1989 	OMUserDataPtr omudp;
1990 	VSMWinPtr vsmwp;
1991 
1992 
1993     /***
1994 	Message(MSG_OK, "VSeqMgrMsgFunc [%d]", (int)message);
1995 	***/
1996 
1997 
1998 	omudp = (OMUserDataPtr)(ommsp->omuserdata);
1999 	vsmwp = (VSMWinPtr)(omudp->userdata.ptrvalue);
2000 
2001 	switch (ommsp->message)
2002 	{
2003 		case OM_MSG_DEL:
2004 			if (! ommsp->entityID) {  /* deleting desktop */
2005 				VSMWinDelete(vsmwp, ommsp->entityID, ommsp->itemID, ommsp->itemtype);
2006 		    }
2007 			break;
2008 		case OM_MSG_CREATE:
2009 			VSMWinRefreshData(vsmwp, ommsp->entityID, ommsp->itemID, ommsp->itemtype);
2010 			break;
2011 		case OM_MSG_UPDATE:
2012 			break;
2013 		case OM_MSG_SELECT:          /* add highlight code */
2014 			break;
2015 		case OM_MSG_DESELECT:        /* add deselect code */
2016 			break;
2017 		case OM_MSG_CACHED:
2018 			break;
2019 		case OM_MSG_UNCACHED:
2020 			break;
2021 		case OM_MSG_TO_CLIPBOARD:  /* this is just because no clipboard now */
2022 			Beep();
2023 			VSMWinRefreshData(vsmwp, ommsp->entityID, ommsp->itemID, ommsp->itemtype);
2024 			break;
2025 		default:
2026 			break;
2027 	}
2028 
2029 	return OM_MSG_RET_OK;
2030 }
2031 
2032 /*****************************************************************************
2033 *
2034 *   VSMPictMsgFunc()
2035 *   	function to call on each entity window by the ObjMgr
2036 *
2037 *****************************************************************************/
VSMPictMsgFunc(OMMsgStructPtr ommsp)2038 Int2 LIBCALLBACK VSMPictMsgFunc (OMMsgStructPtr ommsp)
2039 {
2040 	OMUserDataPtr omudp;
2041 	VSMWinPtr vsmwp;
2042 	VSMPictPtr vsmpp=NULL;
2043 	Boolean do_add = FALSE, do_refresh = FALSE;
2044 
2045     /***
2046 	Message(MSG_OK, "VSMPictMsgFunc [%d]", (int)message);
2047 	***/
2048 
2049 
2050 	omudp = (OMUserDataPtr)(ommsp->omuserdata);
2051 	vsmpp = (VSMPictPtr)(omudp->userdata.ptrvalue);
2052 	vsmwp = vsmpp->vsmwin;
2053 
2054 
2055 	switch (ommsp->message)
2056 	{
2057 		case OM_MSG_DEL:
2058 			if ((vsmwp->entityID == ommsp->entityID) &&
2059 					(vsmwp->itemID == ommsp->itemID) &&
2060 					(vsmwp->itemtype == ommsp->itemtype))
2061 				VSMWinDelete(vsmwp, ommsp->entityID, ommsp->itemID, ommsp->itemtype);
2062 			else if ((! ommsp->itemID) && (! ommsp->itemtype))
2063 			{
2064 				vsmpp->deleted = TRUE;
2065 				do_refresh = TRUE;
2066 			}
2067 			else
2068 				do_add = TRUE;
2069 			break;
2070 		case OM_MSG_CREATE:  /* this is called because desktop function added picture */
2071 			break;
2072 		case OM_MSG_UPDATE:
2073 			do_add = TRUE;
2074 			break;
2075 		case OM_MSG_SELECT:          /* add highlight code */
2076 			VSMPictSelect(vsmpp, ommsp->entityID, ommsp->itemID, ommsp->itemtype, TRUE);
2077 			break;
2078 		case OM_MSG_DESELECT:        /* add deselect code */
2079 			VSMPictSelect(vsmpp, ommsp->entityID, ommsp->itemID, ommsp->itemtype, FALSE);
2080 			break;
2081 		case OM_MSG_CACHED:
2082 			do_add = TRUE;
2083 			break;
2084 		case OM_MSG_UNCACHED:
2085 			do_add = TRUE;
2086 			break;
2087 		case OM_MSG_TO_CLIPBOARD:
2088 			if (vsmwp->is_clipboard)
2089 				do_refresh = TRUE;
2090 			break;
2091 		default:
2092 			break;
2093 	}
2094 	if (do_add)
2095 	{
2096 		VSMAddPictureToEntity(vsmwp, ommsp->entityID, 0);
2097 		do_refresh = TRUE;
2098 	}
2099 
2100 	if (do_refresh)
2101 	{
2102 		VSMWinRefreshData(vsmwp, ommsp->entityID, ommsp->itemID, ommsp->itemtype);
2103 	}
2104 
2105 	return OM_MSG_RET_OK;
2106 }
2107 
2108 typedef struct vsmhlp {
2109 	Uint2 h_item, h_type;
2110 	VieweR h_v;
2111 	Int1 highlight;
2112 } VSMHlp, PNTR VSMHlpPtr;
2113 
VSMHighlightProc(SegmenT seg,PrimitivE prim,Uint2 segid,Uint2 primID,Uint2 primct,Pointer data)2114 static Boolean VSMHighlightProc (SegmenT seg, PrimitivE prim, Uint2 segid, Uint2 primID, Uint2 primct, Pointer data)
2115 {
2116 	VSMHlpPtr vhp;
2117 
2118 	vhp = (VSMHlpPtr)data;
2119 
2120 	if (segid == vhp->h_type)
2121 	{
2122 		if (primID == vhp->h_item)
2123 		{
2124 			HighlightSegment(vhp->h_v, seg, vhp->highlight);
2125 			return FALSE;
2126 		}
2127 	}
2128 	return TRUE;
2129 }
2130 
2131 /*****************************************************************************
2132 *
2133 *	VSMPictSelect(vspp, entityID, itemID, itemtype, select)
2134 *
2135 *****************************************************************************/
VSMPictSelect(VSMPictPtr vsmpp,Uint2 entityID,Uint4 itemID,Uint2 itemtype,Boolean select)2136 static void NEAR VSMPictSelect(VSMPictPtr vsmpp, Uint2 entityID, Uint4 itemID, Uint2 itemtype, Boolean select)
2137 {
2138 
2139 	VieweR v;
2140 	VSMHlp vh;
2141 	VSMWinPtr vsmwp;
2142 
2143 
2144 	if (vsmpp == NULL) return;
2145 	if (vsmpp->s == NULL) return;
2146 	if (vsmpp->vsmwin == NULL) return;
2147     vsmwp = (VSMWinPtr)(vsmpp->vsmwin);
2148 	v = GetWindowExtra(vsmwp->w);
2149 
2150 	vh.h_v = v;
2151 	vh.h_item = itemID;
2152 	vh.h_type = itemtype;
2153 	if (select)
2154 		vh.highlight = OUTLINE_SEGMENT;
2155 	else
2156 		vh.highlight = PLAIN_SEGMENT;
2157 
2158 
2159 	if (! itemID)
2160 		HighlightSegment(v, vsmpp->s, vh.highlight);
2161 	else
2162 		ExploreSegment(vsmpp->s, (Pointer)(&vh), VSMHighlightProc);
2163 
2164  	return;
2165 }
2166 
add_frame(SegmenT seg,Int4 left,Int4 top,Int4 right,Int4 bottom,Uint2 primID)2167 static void add_frame (SegmenT seg, Int4 left, Int4 top, Int4 right,
2168                                                      Int4 bottom, Uint2 primID)
2169 {
2170   AddInvFrame ( seg, left, top, right, bottom, primID );
2171 }
2172 
2173 typedef struct vsmgp {
2174 	SegmenT segs[20];
2175 	VSeqMgrPtr vsmp;
2176 	Int4 currline;
2177 	Uint1 level[OBJ_MAX];
2178 	SegmenT annotseg, descrseg;
2179 } VSMGatherProcST, PNTR VSMGatherProcSTPtr;
2180 
VSMGatherPictProc(GatherContextPtr gcp)2181 static Boolean VSMGatherPictProc (GatherContextPtr gcp)
2182 {
2183 	VSMGatherProcSTPtr vsmgp;
2184 	VSeqMgrPtr vsmp;
2185 	Char buf[101];
2186 	CharPtr tmp;
2187 	Int2 i, k, buflen;
2188 	Int4 top, lineheight, left, bottom, width, maxwidth;
2189 	SegmenT seg;
2190 	Uint1 shading, setcolor[3];
2191 	Uint1Ptr tcolor;
2192 	BioseqPtr bsp;
2193 	BioseqSetPtr bssp;
2194 	ObjMgrTypePtr omtp;
2195 	ValNode vn;
2196 	SeqFeatPtr sfp;
2197 	SeqAnnotPtr annot;
2198 	SeqGraphPtr sgp;
2199 	ValNodePtr desc;
2200 	ObjectIdPtr oip;
2201 	SeqIdPtr sip;
2202 	UserFieldPtr ufp;
2203 	UserObjectPtr uop;
2204 	SeqEntryPtr sep;
2205 	SeqEntryPtr oldsep;
2206 
2207 	vsmgp = (VSMGatherProcSTPtr)(gcp->userdata);
2208 	vsmp = vsmgp->vsmp;
2209 	lineheight = vsmp->lineheight;
2210 	top = vsmgp->currline * (lineheight + 2);
2211 	left = vsmp->charw * gcp->indent;
2212 
2213 	i = gcp->indent + 1;   /* level 0 is the entity segment */
2214 
2215 	SelectFont(vsmp->font);
2216 	omtp = ObjMgrTypeFind(vsmp->omp, gcp->thistype, NULL, NULL);
2217 
2218 	sep = GetTopSeqEntryForEntityID (gcp->entityID);
2219 	oldsep = SeqEntrySetScope (sep);
2220 
2221 	switch (gcp->thistype)
2222 	{
2223 		case OBJ_SEQSUB:
2224 		case OBJ_SUBMIT_BLOCK:
2225 			if (vsmgp->level[gcp->thistype] < 2)
2226 				buflen = 40;
2227 			else
2228 				buflen = 80;
2229 			seg = CreateSegment(vsmgp->segs[gcp->indent], (Uint2)(gcp->thistype), 0);
2230 			vsmgp->segs[i] = seg;
2231 			bottom = top - lineheight;
2232 
2233 			AddAttribute(seg, COLOR_ATT, WHITE_COLOR,0, 0, 0, 0);
2234 			AddSegRect(seg, TRUE, gcp->itemID);
2235 			AddAttribute(seg, COLOR_ATT, BLACK_COLOR,0, 0, 0, 0);
2236 			AddSegRect(seg, FALSE, gcp->itemID);
2237 			if (gcp->thistype == OBJ_SEQSUB)
2238 				StringMove(buf, "Data Submission");
2239 			else
2240 				(*(omtp->labelfunc))(gcp->thisitem, buf, buflen, OM_LABEL_BOTH);
2241 
2242 			width = StringWidth(buf) + (2 * vsmp->charw);
2243 				               /* this just forces the segment size */
2244 			add_frame(seg, left, top-2, (left+width), (top-lineheight+2), gcp->itemID);
2245 			AddTextLabel(seg, left+(vsmp->charw), top, buf, vsmp->font,0,LOWER_RIGHT,gcp->itemID);
2246 			vsmgp->currline--;
2247 			break;
2248 		case OBJ_SEQSUB_CONTACT:
2249 		case OBJ_SEQSUB_CIT:
2250 			if (vsmgp->level[gcp->thistype] < 2)
2251 				buflen = 40;
2252 			else
2253 				buflen = 80;
2254 			seg = CreateSegment(vsmgp->segs[gcp->indent], (Uint2)(gcp->thistype), 0);
2255 			vsmgp->segs[i] = seg;
2256 			bottom = top - lineheight;
2257 
2258 			if (gcp->thistype == OBJ_SEQSUB_CIT)
2259 			{
2260 				vn.choice = PUB_Sub;
2261 				vn.data.ptrvalue = gcp->thisitem;
2262 				vn.next = NULL;
2263 				omtp = ObjMgrTypeFind(vsmp->omp, OBJ_PUB, NULL, NULL);
2264 				tmp = StringMove(buf, "Cit: ");
2265 				(*(omtp->labelfunc))((Pointer)(&vn), tmp, (buflen - 5), OM_LABEL_CONTENT);
2266 			}
2267 			else
2268 				(*(omtp->labelfunc))(gcp->thisitem, buf, buflen, OM_LABEL_BOTH);
2269 			width = StringWidth(buf) + (2 * vsmp->charw);
2270 				               /* this just forces the segment size */
2271 			add_frame(seg, left, top-2, (left+width), (top-lineheight+2), gcp->itemID);
2272 			AddAttribute(seg, COLOR_ATT, BLACK_COLOR,0, 0, 0, 0);
2273 			AddTextLabel(seg, left+(vsmp->charw), top, buf, vsmp->font,0,LOWER_RIGHT,gcp->itemID);
2274 			vsmgp->currline--;
2275 			break;
2276 		case OBJ_BIOSEQSET:
2277 			seg = CreateSegment(vsmgp->segs[gcp->indent], (Uint2)(gcp->thistype), 0);
2278 			vsmgp->segs[i] = seg;
2279 			bssp = (BioseqSetPtr)(gcp->thisitem);
2280 			bottom = top - lineheight;
2281 
2282 			if (gcp->indent > 3)
2283 				k = 3;
2284               else
2285 				k = gcp->indent;
2286 			shading = (Uint1)(140 + (k * 20));
2287 
2288 			for (k = 0; k < 3; k++)
2289 				setcolor[k] = shading;
2290 
2291 			AddAttribute(seg, COLOR_ATT, setcolor,0, 0, 0, 0);
2292 			AddSegRect(seg, TRUE, gcp->itemID);
2293 			(*(omtp->labelfunc))(gcp->thisitem, buf, 40, OM_LABEL_TYPE);
2294 			width = StringWidth(buf) + (2 * vsmp->charw);
2295 				               /* this just forces the segment size */
2296 			add_frame(seg, left, top-2, (left+width), (top-lineheight+2), gcp->itemID);
2297 			AddAttribute(seg, COLOR_ATT, BLUE_COLOR, 0, 0, 0,0);
2298 			AddTextLabel(seg, left+(vsmp->charw), top, buf, vsmp->font,0,LOWER_RIGHT,gcp->itemID);
2299 			vsmgp->currline--;
2300 			break;
2301 		case OBJ_BIOSEQ:
2302 			seg = CreateSegment(vsmgp->segs[gcp->indent], (Uint2)(gcp->thistype), 0);
2303 			vsmgp->segs[i] = seg;
2304 			(*(omtp->labelfunc))(gcp->thisitem, buf, 40, OM_LABEL_CONTENT);
2305 			bsp = (BioseqPtr)(gcp->thisitem);
2306 			width = StringWidth(buf) + (2 * vsmp->charw);
2307 			maxwidth = width;
2308 
2309 			if (ISA_aa(bsp->mol))
2310 				tcolor = MAGENTA_COLOR;
2311 			else
2312 				tcolor = RED_COLOR;
2313 												/* just to force segment size */
2314 			AddAttribute(seg, COLOR_ATT , WHITE_COLOR, 0, 0,0,0);
2315 
2316 			if (vsmgp->level[OBJ_BIOSEQ] > 1)
2317 				k = 2;
2318 			else
2319 				k = 1;
2320 			AddSegRect(seg, TRUE, gcp->itemID);
2321 			AddAttribute(seg, COLOR_ATT , tcolor, 0, 0,0,0);
2322 			AddSegRect(seg, FALSE, gcp->itemID);
2323 			AddTextLabel(seg, left + vsmp->charw, top, buf, vsmp->font,0, LOWER_RIGHT,gcp->itemID);
2324 			vsmgp->currline--;
2325 			if (k == 2)
2326 			{
2327 				(*(omtp->labelfunc))(gcp->thisitem, buf, 40, OM_LABEL_TYPE);
2328 				SelectFont(vsmp->font);
2329 				width = StringWidth(buf) + (3 * vsmp->charw);
2330 				if (width > maxwidth)
2331 					maxwidth = width;
2332 				AddTextLabel(seg, left + (2 * vsmp->charw), (top - lineheight), buf, vsmp->font,0, LOWER_RIGHT,gcp->itemID);
2333 				vsmgp->currline--;
2334 			}
2335 			if (vsmgp->level[OBJ_BIOSEQ] == 3)
2336 			{
2337 				if (bsp->repr == Seq_repr_seg)
2338 				{
2339 					k = 3;
2340 					vn.choice = SEQLOC_MIX;
2341 					vn.data.ptrvalue = bsp->seq_ext;
2342 					vn.next = NULL;
2343 					SeqLocLabel(&vn, buf, 80, OM_LABEL_CONTENT);
2344 					SelectFont(vsmp->font);
2345 					width = StringWidth(buf) + (3 * vsmp->charw);
2346 					if (width > maxwidth)
2347 						maxwidth = width;
2348 					AddTextLabel(seg, left + (2 * vsmp->charw), (top - (2*lineheight)), buf, vsmp->font,0, LOWER_RIGHT,gcp->itemID);
2349 					vsmgp->currline--;
2350 				}
2351 			}
2352 			add_frame(seg, left, top-2, (left+maxwidth), (top-(k * lineheight)+2), gcp->itemID);
2353 			break;
2354 		case OBJ_SEQANNOT:
2355 			(*(omtp->labelfunc))(gcp->thisitem, buf, 40, OM_LABEL_BOTH);
2356 			if (vsmgp->level[OBJ_SEQANNOT] > 1) {
2357 			  annot = (SeqAnnotPtr) gcp->thisitem;
2358 			  if (annot != NULL) {
2359 			    for (desc = annot->desc; desc != NULL; desc = desc->next) {
2360 			      if (desc->choice == Annot_descr_name) {
2361 			        StringCat (buf, " (");
2362 			        StringNCat (buf, desc->data.ptrvalue, 35);
2363 			        StringCat (buf, ")");
2364 			      }
2365 			    }
2366 			  }
2367 			}
2368 			width = StringWidth(buf);
2369 			seg = CreateSegment(vsmgp->segs[gcp->indent], (Uint2)(gcp->thistype), 0);
2370 			vsmgp->segs[i] = seg;
2371 			AddAttribute(seg, COLOR_ATT, BLUE_COLOR, 0,0,0,0);
2372 			AddSegRect(seg, FALSE, gcp->itemID);
2373 			AddTextLabel(seg, left, top, buf, vsmp->font,0, LOWER_RIGHT,gcp->itemID);
2374 			add_frame(seg, left, top, (left+width), (top-lineheight), gcp->itemID);
2375 			vsmgp->currline--;
2376 			break;
2377 		case OBJ_SEQALIGN:
2378 			if (vsmgp->level[OBJ_SEQALIGN] < 2)
2379 				buflen = 40;
2380 			else
2381 				buflen = 80;
2382 			seg = CreateSegment(vsmgp->segs[gcp->indent], (Uint2)(gcp->thistype), 0);
2383 			vsmgp->segs[i] = seg;
2384 			(*(omtp->labelfunc))(gcp->thisitem, buf, buflen, OM_LABEL_BOTH);
2385 			width = StringWidth(buf) + (2 * vsmp->charw);
2386 			AddAttribute(seg, COLOR_ATT , BLUE_COLOR, 0, 0,0,0);
2387 			AddTextLabel(seg, left + vsmp->charw, top, buf, vsmp->font,0, LOWER_RIGHT,gcp->itemID);
2388 			add_frame(seg, left+vsmp->charw, top, (left+width), (top-lineheight), gcp->itemID);
2389 			vsmgp->currline--;
2390 			break;
2391 		case OBJ_ANNOTDESC:
2392 			if (vsmgp->level[OBJ_ANNOTDESC] < 2)
2393 				buflen = 40;
2394 			else
2395 				buflen = 80;
2396 			seg = CreateSegment(vsmgp->segs[gcp->indent], (Uint2)(gcp->thistype), 0);
2397 			vsmgp->segs[i] = seg;
2398 			(*(omtp->labelfunc))(gcp->thisitem, buf, buflen, OM_LABEL_BOTH);
2399 			width = StringWidth(buf) + (2 * vsmp->charw);
2400 			add_frame(seg, left, top-2, (left+width), (top-lineheight+2), gcp->itemID);
2401 			AddAttribute(seg, COLOR_ATT , CYAN_COLOR, 0, 0,0,0);
2402 			AddTextLabel(seg, left + vsmp->charw, top, buf, vsmp->font,0, LOWER_RIGHT,gcp->itemID);
2403 			vsmgp->currline--;
2404 			break;
2405 		case OBJ_SEQGRAPH:
2406 			if (vsmgp->level[OBJ_SEQGRAPH] < 2)
2407 				buflen = 40;
2408 			else
2409 				buflen = 80;
2410 			seg = CreateSegment(vsmgp->segs[gcp->indent], (Uint2)(gcp->thistype), 0);
2411 			vsmgp->segs[i] = seg;
2412 			(*(omtp->labelfunc))(gcp->thisitem, buf, buflen, OM_LABEL_BOTH);
2413 			width = StringWidth(buf) + (2 * vsmp->charw);
2414 			AddAttribute(seg, COLOR_ATT , BLUE_COLOR, 0, 0,0,0);
2415 			AddTextLabel(seg, left + vsmp->charw, top, buf, vsmp->font,0, LOWER_RIGHT,gcp->itemID);
2416 			vsmgp->currline--;
2417 			maxwidth = width;
2418 			k = 1;
2419 			sgp = (SeqGraphPtr) gcp->thisitem;
2420 			if (vsmgp->level[OBJ_SEQGRAPH] > 1 && sgp != NULL && sgp->loc != NULL) {
2421 				k++;
2422 				SeqLocLabel(sgp->loc, buf, buflen, OM_LABEL_CONTENT);
2423 				SelectFont(vsmp->font);
2424 				width = StringWidth(buf) + (3 * vsmp->charw);
2425 				if (width > maxwidth)
2426 					maxwidth = width;
2427 				AddTextLabel(seg, left + (2*vsmp->charw), (top-lineheight), buf, vsmp->font,0, LOWER_RIGHT,gcp->itemID);
2428 				vsmgp->currline--;
2429 			}
2430 			add_frame(seg, left, top-2, (left+width), (top-(k*lineheight)+2), gcp->itemID);
2431 			/* add_frame(seg, left+vsmp->charw, top, (left+width), (top-lineheight), (Uint2)(gcp->itemID)); */
2432 			break;
2433 		case OBJ_SEQFEAT:
2434 			if (vsmgp->level[OBJ_SEQFEAT] < 2)
2435 				buflen = 40;
2436 			else
2437 				buflen = 80;
2438 			seg = CreateSegment(vsmgp->segs[gcp->indent], (Uint2)(gcp->thistype), 0);
2439 			vsmgp->segs[i] = seg;
2440 			(*(omtp->labelfunc))(gcp->thisitem, buf, buflen, OM_LABEL_BOTH);
2441 			/*
2442 			buf [0] = '\0';
2443 			sfp = (SeqFeatPtr)(gcp->thisitem);
2444 			str = FindKeyFromFeatDefType (sfp->idx.subtype, FALSE);
2445 			if (str != NULL) {
2446 			  StringNCpy_0 (buf, str, sizeof (buf));
2447 			  if (SeqMgrGetDesiredFeature (sfp->idx.entityID, NULL, 0, 0, sfp, &fcontext) == sfp) {
2448 			    str = fcontext.label;
2449 			    if (str != NULL) {
2450 			      StringNCpy_0 (lbl, str, sizeof (lbl));
2451 			      StringCat (buf, ": ");
2452 			      StringCat (buf, lbl);
2453             if (StringLen (buf) > buflen - 2) {
2454               buf [buflen - 2] = '>';
2455               buf [buflen - 1] = '\0';
2456             }
2457 			    }
2458 			  }
2459 			}
2460 			if (buf [0] == '\0') {
2461 			  (*(omtp->labelfunc))(gcp->thisitem, buf, buflen, OM_LABEL_BOTH);
2462 			}
2463 			*/
2464 			width = StringWidth(buf) + (2 * vsmp->charw);
2465 			AddAttribute(seg, COLOR_ATT , BLUE_COLOR, 0, 0,0,0);
2466 			AddTextLabel(seg, left + vsmp->charw, top, buf, vsmp->font,0, LOWER_RIGHT,gcp->itemID);
2467 			vsmgp->currline--;
2468 			maxwidth = width;
2469 			k = 1;
2470 			if (vsmgp->level[OBJ_SEQFEAT] == 2)
2471 			{
2472 				k++;
2473 				sfp = (SeqFeatPtr)(gcp->thisitem);
2474 				SeqLocLabel(sfp->location, buf, buflen, OM_LABEL_CONTENT);
2475 				SelectFont(vsmp->font);
2476 				width = StringWidth(buf) + (3 * vsmp->charw);
2477 				if (width > maxwidth)
2478 					maxwidth = width;
2479 				AddTextLabel(seg, left + (2*vsmp->charw), (top-lineheight), buf, vsmp->font,0, LOWER_RIGHT,gcp->itemID);
2480 				vsmgp->currline--;
2481 				if (vsmp != NULL && vsmp->extraLevel && sfp->product != NULL) {
2482 					k++;
2483 					StringCpy (buf, "product ");
2484 					SeqLocLabel(sfp->product, buf + 8, buflen - 8, OM_LABEL_CONTENT);
2485 					SelectFont(vsmp->font);
2486 					width = StringWidth(buf) + (3 * vsmp->charw);
2487 					if (width > maxwidth)
2488 						maxwidth = width;
2489 					AddTextLabel(seg, left + (2*vsmp->charw), (top-lineheight*2), buf, vsmp->font,0, LOWER_RIGHT,gcp->itemID);
2490 					vsmgp->currline--;
2491 				}
2492 				if (vsmp != NULL && vsmp->extraLevel && sfp->data.choice == SEQFEAT_RNA && sfp->ext != NULL) {
2493 					/* uop = sfp->ext; */
2494 					uop = FindUopByTag (sfp->ext, "MrnaProteinLink");
2495 					if (uop != NULL && uop->type != NULL && StringICmp (uop->type->str, "MrnaProteinLink") == 0) {
2496 						ufp = uop->data;
2497 						if (ufp != NULL && ufp->choice == 1) {
2498 							oip = ufp->label;
2499 							if (oip != NULL && oip->str != NULL && StringICmp (oip->str, "protein seqID") == 0) {
2500 								tmp = (CharPtr) ufp->data.ptrvalue;
2501 								if (tmp != NULL) {
2502 									sip = MakeSeqID (tmp);
2503 									if (sip != NULL) {
2504 										vn.choice = SEQLOC_WHOLE;
2505 										vn.data.ptrvalue = (Pointer) sip;
2506 										k++;
2507 										StringCpy (buf, "protein ");
2508 										SeqLocLabel(&vn, buf + 8, buflen - 8, OM_LABEL_CONTENT);
2509 										SelectFont(vsmp->font);
2510 										width = StringWidth(buf) + (3 * vsmp->charw);
2511 										if (width > maxwidth)
2512 											maxwidth = width;
2513 										AddTextLabel(seg, left + (2*vsmp->charw), (top-lineheight*(k-1)), buf, vsmp->font,0, LOWER_RIGHT,gcp->itemID);
2514 										vsmgp->currline--;
2515 										SeqIdFree (sip);
2516 									}
2517 								}
2518 							}
2519 						}
2520 					}
2521 				}
2522 			}
2523 			add_frame(seg, left, top-2, (left+width), (top-(k*lineheight)+2), gcp->itemID);
2524 			break;
2525 		case OBJ_SEQDESC:
2526 			if (vsmgp->level[OBJ_SEQDESC] < 2)
2527 				buflen = 40;
2528 			else
2529 				buflen = 80;
2530 			seg = CreateSegment(vsmgp->segs[gcp->indent], (Uint2)(gcp->thistype), 0);
2531 			vsmgp->segs[i] = seg;
2532 			(*(omtp->labelfunc))(gcp->thisitem, buf, buflen, OM_LABEL_BOTH);
2533 			width = StringWidth(buf) + (2 * vsmp->charw);
2534 			add_frame(seg, left, top-2, (left+width), (top-lineheight+2), gcp->itemID);
2535 			AddAttribute(seg, COLOR_ATT , BLACK_COLOR, 0, 0,0,0);
2536 			AddTextLabel(seg, left + vsmp->charw, top, buf, vsmp->font,0, LOWER_RIGHT, gcp->itemID);
2537 			vsmgp->currline--;
2538 			break;
2539 		default:
2540 			break;
2541 
2542 	}
2543 
2544 	SeqEntrySetScope (oldsep);
2545 
2546 	return TRUE;
2547 }
2548 
2549 /*****************************************************************************
2550 *
2551 *   VSMEntityDraw(omdp)
2552 *
2553 *****************************************************************************/
VSMEntityDraw(ObjMgrDataPtr omdp,VSMPictPtr vsmpp,VSeqMgrPtr vsmp)2554 SegmenT VSMEntityDraw (ObjMgrDataPtr omdp, VSMPictPtr vsmpp, VSeqMgrPtr vsmp)
2555 {
2556 	VSMGatherProcST vsg;
2557 	GatherScope gs;
2558 	SegmenT top = NULL, seg;
2559 	CharPtr tmp=NULL;
2560 	Char buf[41];
2561 	ObjMgrTypePtr omtp;
2562 	Int2 width, expansion, i, width2;
2563 	Boolean maxexpansion = FALSE;
2564 	Int4 bottom, maxwidth;
2565 	Uint1 tcolor[3];
2566 	Boolean extraLevel = FALSE;
2567 
2568 	MemSet(&vsg, 0, sizeof(VSMGatherProcST));
2569 	MemSet(&gs, 0, sizeof(GatherScope));
2570 
2571 	MemSet(gs.ignore, (int)(TRUE), (size_t)OBJ_MAX);
2572 	gs.nointervals = TRUE;
2573 	gs.do_not_reload_from_cache = TRUE;
2574 
2575 	if (vsmpp->expansion < 0)
2576 		vsmpp->expansion = 0;
2577 
2578 	expansion = vsmpp->expansion;
2579 		switch (omdp->datatype)
2580 		{
2581 			case OBJ_SEQSUB:
2582 				if (expansion)
2583 				{
2584 					vsg.level[OBJ_SEQSUB] = 1;
2585 					vsg.level[OBJ_SUBMIT_BLOCK] = 1;
2586 				}
2587 				if (expansion > 1)
2588 				{
2589 					vsg.level[OBJ_SEQSUB_CONTACT] = 1;
2590 					vsg.level[OBJ_SEQSUB_CIT] = 1;
2591 				}
2592 				if (expansion > 2)
2593 				{
2594 					vsg.level[OBJ_SUBMIT_BLOCK] = 2;
2595 					vsg.level[OBJ_SEQSUB_CONTACT] = 2;
2596 					vsg.level[OBJ_SEQSUB_CIT] = 2;
2597 				}
2598 			case OBJ_BIOSEQ:
2599 			case OBJ_BIOSEQSET:
2600 				if (expansion)
2601 				{
2602 					vsg.level[OBJ_BIOSEQ] = 1;
2603 					vsg.level[OBJ_BIOSEQSET] = 1;
2604 				}
2605 				if (vsmp != NULL && vsmp->extraLevel) {
2606 					extraLevel = TRUE;
2607 				}
2608 				if (expansion > 1 && (! extraLevel)) {
2609 					expansion++;
2610 				}
2611 				if (expansion > 1)
2612 				{
2613 					vsg.level[OBJ_BIOSEQ] = 2;
2614 					vsg.level[OBJ_SEQDESC] = 1;
2615 					vsg.level[OBJ_SEQANNOT] = 1;
2616 				}
2617 				if (expansion > 2)
2618 				{
2619 					vsg.level[OBJ_BIOSEQ] = 2;
2620 					vsg.level[OBJ_SEQDESC] = 1;
2621 					vsg.level[OBJ_SEQANNOT] = 1;
2622 					vsg.level[OBJ_ANNOTDESC] = 1;
2623 					vsg.level[OBJ_SEQFEAT] = 1;
2624 					vsg.level[OBJ_SEQGRAPH] = 1;
2625 					vsg.level[OBJ_SEQALIGN] = 1;
2626 				}
2627 				if (expansion > 3)
2628 				{
2629 					vsg.level[OBJ_BIOSEQ] = 3;
2630 					vsg.level[OBJ_SEQDESC] = 2;
2631 					vsg.level[OBJ_SEQANNOT] = 2;
2632 					vsg.level[OBJ_ANNOTDESC] = 2;
2633 					vsg.level[OBJ_SEQFEAT] = 2;
2634 					vsg.level[OBJ_SEQGRAPH] = 2;
2635 					vsg.level[OBJ_SEQALIGN] = 2;
2636 					maxexpansion = TRUE;
2637 				}
2638 				if (expansion > 4)
2639 					vsmpp->expansion = 4;
2640 				break;
2641 			case OBJ_SEQANNOT:
2642 				if (expansion)
2643 				{
2644 					vsg.level[OBJ_SEQANNOT] = 1;
2645 				}
2646 				if (expansion > 1)
2647 				{
2648 					vsg.level[OBJ_SEQANNOT] = 1;
2649 					vsg.level[OBJ_ANNOTDESC] = 1;
2650 					vsg.level[OBJ_SEQFEAT] = 1;
2651 					vsg.level[OBJ_SEQGRAPH] = 1;
2652 					vsg.level[OBJ_SEQALIGN] = 1;
2653 				}
2654 				if (expansion > 2)
2655 				{
2656 					vsg.level[OBJ_ANNOTDESC] = 2;
2657 					vsg.level[OBJ_SEQFEAT] = 2;
2658 					vsg.level[OBJ_SEQGRAPH] = 2;
2659 					vsg.level[OBJ_SEQALIGN] = 2;
2660 					maxexpansion = TRUE;
2661 				}
2662 				if (expansion > 3)
2663 					vsmpp->expansion = 3;
2664 				break;
2665 			case OBJ_SEQFEAT:
2666 				if (expansion)
2667 				{
2668 					vsg.level[OBJ_SEQFEAT] = 2;
2669 					maxexpansion = TRUE;
2670 				}
2671 				if (expansion > 1)
2672 					vsmpp->expansion = 1;
2673 				break;
2674 			case OBJ_SEQALIGN:
2675 				if (expansion)
2676 				{
2677 					vsg.level[OBJ_SEQALIGN] = 2;
2678 					maxexpansion = TRUE;
2679 				}
2680 				if (expansion > 1)
2681 					vsmpp->expansion = 1;
2682 				break;
2683 			case OBJ_SEQGRAPH:
2684 				if (expansion)
2685 				{
2686 					vsg.level[OBJ_SEQGRAPH] = 2;
2687 					maxexpansion = TRUE;
2688 				}
2689 				if (expansion > 1)
2690 					vsmpp->expansion = 1;
2691 				break;
2692 			default:
2693 				vsmpp->expansion = 0;
2694 				maxexpansion = TRUE;
2695 				break;
2696 		}
2697 
2698 	for (i = 0; i < OBJ_MAX; i++)
2699 	{
2700 		if (vsg.level[i])
2701 			gs.ignore[i] = FALSE;
2702 	}
2703 
2704 	vsg.vsmp = vsmp;
2705 	                                      /* default label */
2706 
2707 	top = CreateSegment(NULL, omdp->EntityID, 0);
2708 	omtp = ObjMgrTypeFind(vsmp->omp, omdp->datatype, NULL, NULL);
2709 
2710 	seg = CreateSegment(top, omdp->datatype, 0);  /* 2nd level necessary if not gather */
2711 	vsg.segs[0] = seg;
2712 	if (omtp->label != NULL)
2713 		tmp = omtp->label;
2714 	else if (omtp->name != NULL)
2715 		tmp = omtp->name;
2716 	else
2717 		tmp = omtp->asnname;
2718 	width = LabelCopyExtra(buf, tmp, 40, NULL, ": ");
2719 	tmp = buf + width;
2720 	width = 40 - width;
2721 	(*(omtp->labelfunc))(omdp->dataptr, tmp, width, OM_LABEL_TYPE);
2722 	SelectFont(vsmp->font);
2723 	width = StringWidth(buf) + (3 * vsmp->charw) + 20;
2724 	maxwidth = width;
2725 
2726 	AddAttribute(seg, COLOR_ATT, WHITE_COLOR, 0, 0, 0,0);
2727 	AddSegRect(seg, TRUE, 0);
2728 
2729 	if (omdp->tempload == TL_CACHED)
2730 	{
2731 		tcolor[0] = 0;
2732 		tcolor[1] = 128;
2733 		tcolor[2] = 128;
2734 		AddAttribute(seg, COLOR_ATT, tcolor, 0, 0, 0,0);
2735 	}
2736 	else if (omdp->tempload == TL_LOADED)
2737 	{
2738 		tcolor[0] = 0;
2739 		tcolor[1] = 128;
2740 		tcolor[2] = 64;
2741 		AddAttribute(seg, COLOR_ATT, tcolor, 0, 0, 0,0);
2742 	}
2743 	else if (omdp->clipboard)
2744 		AddAttribute(seg, COLOR_ATT, RED_COLOR, 0, 0, 0,0);
2745 	else
2746 		AddAttribute(seg, COLOR_ATT, BLUE_COLOR, 0, 0, 0,0);
2747 	AddSegRect(seg, FALSE, 0);
2748 
2749 	bottom = (Int4)(vsmp->lineheight + (vsmp->lineheight/2));
2750 
2751 	AddTextLabel(seg, vsmp->charw, bottom, buf, vsmp->font,0,UPPER_RIGHT,0);
2752 
2753 	bottom -= vsmp->lineheight;
2754 
2755 	if ((*(omtp->labelfunc))(omdp->dataptr, buf, 40, OM_LABEL_CONTENT))
2756 	{
2757 		SelectFont(vsmp->font);
2758 		width2 = StringWidth(buf) + (2 * vsmp->charw);
2759 		if (width2 > maxwidth)
2760 			maxwidth = width2;
2761 		AddTextLabel(seg, vsmp->charw,bottom,buf, vsmp->font,0,UPPER_RIGHT,0);
2762 
2763 	}
2764 
2765 	add_frame(seg, 0, (3 * vsmp->lineheight), maxwidth, 0, 0);
2766 
2767     bottom += vsmp->lineheight;
2768     maxwidth -= vsmp->charw;
2769 	if (! maxexpansion)
2770 	{
2771 		AddAttribute(seg, COLOR_ATT, RED_COLOR, 0, 0, 0,0);
2772 		AddRectangle(seg, (Int4)(maxwidth-20), (Int4)(bottom + vsmp->lineheight), (Int4)(maxwidth - 12),
2773 						(Int4)(bottom+4), UP_ARROW, TRUE, (Uint2)VSM_PICT_UP_BUTTON);
2774 						/**
2775 		AddSymbol(seg, (Int4)(width-15), bottom, UP_TRIANGLE_SYMBOL, TRUE,
2776 					UPPER_CENTER, (Uint2) VSM_PICT_UP_BUTTON);
2777 					    **/
2778 	}
2779 	if (vsmpp->expansion)
2780 	{
2781 		AddAttribute(seg, COLOR_ATT, GREEN_COLOR, 0, 0, 0,0);
2782 		AddRectangle(seg, (Int4)(maxwidth-8), (Int4)(bottom + vsmp->lineheight), (Int4)(maxwidth),
2783 						(Int4)(bottom+4), DOWN_ARROW, TRUE, (Uint2)VSM_PICT_DOWN_BUTTON);
2784 	}
2785 
2786 	GatherEntity(omdp->EntityID, &vsg, VSMGatherPictProc, &gs);
2787 
2788 	return top;
2789 }
2790 
VSMFreePictureForEntity(Pointer ptr)2791 static Pointer LIBCALLBACK VSMFreePictureForEntity (Pointer ptr)
2792 {
2793 	VSMPictPtr vsmpp;
2794 
2795 	if (ptr == NULL) return NULL;
2796 
2797 	vsmpp = (VSMPictPtr)ptr;
2798 	if (vsmpp->s != NULL)
2799 	{
2800 		UnlinkSegment(vsmpp->s);
2801 		DeleteSegment(vsmpp->s);
2802 	}
2803 	return MemFree(vsmpp);
2804 }
2805 
2806 /*****************************************************************************
2807 *
2808 *   VSMAddPictureToEntity(vsmwp, entityID, expand)
2809 *   	if segment with picture already present, just refreshes it
2810 *   	else adds the new one
2811 *		expand increments or decrements the expansion of the picture by its value
2812 *
2813 *****************************************************************************/
VSMAddPictureToEntity(VSMWinPtr vsmwp,Uint2 entityID,Int2 expand)2814 static OMUserDataPtr NEAR VSMAddPictureToEntity (VSMWinPtr vsmwp, Uint2 entityID, Int2 expand)
2815 {
2816 	OMUserDataPtr omudp;
2817 	VSMPictPtr vsmpp;
2818 	ObjMgrDataPtr omdp;
2819 	SegmenT seg=NULL;
2820 	ValNodePtr vnp;
2821 	Pointer ptr;
2822 	SelStructPtr ssp;
2823 	VSeqMgrPtr vsmp;
2824 
2825 	if (vsmwp == NULL) return NULL;
2826 											  /* already have it? */
2827 	omudp = ObjMgrGetUserData (entityID, vsmwp->procid, vsmwp->proctype, vsmwp->userkey);
2828 	if (omudp != NULL)   /* have it already */
2829 	{
2830 		vsmpp = (VSMPictPtr)(omudp->userdata.ptrvalue);
2831 		UnlinkSegment(vsmpp->s);
2832 		DeleteSegment(vsmpp->s);
2833 		vsmpp->s = NULL;
2834 	}
2835 	else
2836 	{
2837 		omudp = ObjMgrAddUserData(entityID, vsmwp->procid, vsmwp->proctype,
2838 					vsmwp->userkey);
2839 	    if (omudp == NULL) {
2840 	      return NULL;
2841 	    }
2842 		vsmpp = MemNew(sizeof(VSMPict));
2843 		vsmpp->vsmwin = vsmwp;
2844 		vsmpp->entityID = entityID;
2845 		omudp->userdata.ptrvalue = (Pointer)vsmpp;
2846 		omudp->freefunc = VSMFreePictureForEntity;
2847 		omudp->messagefunc = VSMPictMsgFunc;
2848 	}
2849 
2850 	omdp = ObjMgrGetData(entityID);
2851 	vnp = omdp->choice;
2852 	ptr = omdp->dataptr;
2853 
2854 	vsmpp->expansion += expand;
2855 
2856 	vsmp = vsmwp->vsmp;
2857 	if (vsmp != NULL) {
2858 		vsmp->extraLevel = TRUE;
2859 	}
2860 
2861 	seg = VSMEntityDraw(omdp, vsmpp, vsmwp->vsmp);
2862 
2863 	if (seg == NULL)
2864 		Message(MSG_ERROR, "VSMAddSegmentToPicture: can't handle [%d] [%d]",
2865 			(int)(omdp->choicetype), (int)(omdp->datatype));
2866 	else
2867 	{
2868 		vsmpp->s = seg;
2869 		ssp = ObjMgrGetSelected();
2870 		while (ssp != NULL)
2871 		{
2872 			if (ssp->entityID == entityID)
2873 			{
2874 				VSMPictSelect(vsmpp, entityID, ssp->itemID, ssp->itemtype, TRUE);
2875 			}
2876 			ssp = ssp->next;
2877 		}
2878 	}
2879 
2880 	return omudp;
2881 }
2882