static void pgfilterw_updateFilter ( void ) /************************************************************************ * pgfilterw_updateFilter * * * * Updates the current filter string and then refreshes the display. * * * * static void pgfilterw_updateFilter ( void ) * * * * Input parameters: * * Output parameters: * * none * * * ** * * Log: * * J. Wu/SAIC 07/04 initial coding * * J. Wu/SAIC 08/04 link filter change with GFA window * * J. Wu/SAIC 09/04 Restart GFA for any filter changes * * J. Wu/SAIC 10/04 Access GFA attr with cvg_getFld() * * E. Safford/SAIC 07/05 rm sequence # from cvg_scangfa() call * * M. Li/SAIC 03/07 Not reset fcst hour if change from GFA * * E. Safford/SAIC 05/07 fix gfa' connection * * E. Safford/SAIC 06/07 fix bug in preFilterOn determination * * B. Yin/SAIC 12/07 set GFA hr to last selected filter time * ***********************************************************************/ { int ii, filternum, ier, cur_obj, cur_loc, newel_loc, num; int subtyp, areatyp, len; char lastTime[8], value[32], tag[32], timeCmp[10]; Boolean gfaIsUp = False, gfaInAdd = False, preFilterOn = False; Boolean gfaPrimeIsUp = False; VG_DBStruct cur_el, newel; /*---------------------------------------------------------------------*/ cur_el.elem.gfa.info.nblocks = 0; _curFilter[0] = '\0'; filternum = 0; for ( ii = 0; ii < _nFilTime[TIME_FILTER]; ii++ ) { if ( _filterStatus[ii] ) { filternum++; strcat ( _curFilter, _filTime[TIME_FILTER][ii] ); if ( ii < (_nFilTime[TIME_FILTER] - 1) ) { strcat ( _curFilter, ";" ); } } } /* * If no filter is provided but the filter window is up - none * of the elements with time stamp will be displayed. If the * filter window is down, all elements should be displayed. */ if ( filternum == 0 ) { if ( pgfilterw_isUp() ) { strcpy ( _curFilter, ACTV_FILTER ); } else { strcpy ( _curFilter, CANCEL_FILTER ); } } /* * Check if gfaw is up and its mode. */ gfaIsUp = pggfaw_isUp(); gfaPrimeIsUp = pggfawp_isUp(); if( gfaIsUp ) { gfaInAdd = pggfaw_isAddMode(); } else if( gfaPrimeIsUp ) { gfaInAdd = pggfawp_isAddMode(); } cur_obj = pgpalw_getCurObjId (); /* * If gfaw is up, retrieve the current GFA attributes and check * if the previous forecast hour is still "ON" in filter window. * * If it is still on, then take no action. If it is not, and there * is another time selected, set the GFA/GFA' window forecast hour to * the first selected time. * * Note that the GFA/GFA' will ignore the Airmet and Outlook filter * settings. */ cur_loc = -1; preFilterOn = False; if ( gfaIsUp || gfaPrimeIsUp ) { if ( gfaInAdd ) { if( gfaIsUp ) { pggfaw_getAttr ( &cur_el ); ier = 0; } else { pggfawp_getAttr ( &cur_el ); ier = 0; } } else { cur_loc = pgactv_getElmLoc (); cvg_rdrec ( cvg_getworkfile(), cur_loc, &cur_el, &ier ); } cvg_getFld ( &cur_el, TAG_GFA_FCSTHR, value, &ier ); if ( filternum > 0 && ier == 0 ) { for ( ii = 0; ii < _nFilTime[TIME_FILTER]; ii++ ) { if ( _filterStatus[ii] ) { strcpy( timeCmp, _filTime[TIME_FILTER][ii] ); len = strlen( timeCmp ); if( timeCmp[ len-1 ] == '+' ) { timeCmp[ len-1 ] = '\0'; } if ( strcmp ( value, timeCmp ) == 0 ) { preFilterOn = True; break; } } } } } /* * Update filter setting in CVG library. */ cvg_setfilter ( _curFilter, &ier ); /* * Refresh the display. */ pgfilterw_refresh (); /* * Adjust GFA window, if necessary. */ if ( gfaIsUp || gfaPrimeIsUp ) { /* * If previously in "Add" mode, keep drawing. */ if ( gfaInAdd ) { /* * Set the GFA hour to the last selected filter time. * */ pgfilterw_getLastTime ( lastTime ); if ( strlen ( lastTime ) > (size_t)0 ) { if (!_fromGfa) { if( gfaIsUp ) { pggfaw_setHour ( lastTime ); } else { pggfawp_setHour ( lastTime ); } } } } else { /* Previously in "Edit" mode */ /* * The filter matching the active element's forecast hour * is still ON, keep editing it. */ if ( preFilterOn ) { cvg_freeElPtr( &cur_el ); pghdlb_select ( &cur_el, cur_loc ); } else { /* * The filter matching the active element's forecast * hour is OFF, terminate all pending actions. * However, if it is turned off by pressing hotkeys, * and a GFA element matching the same subtype, * and area type number could be found, * set to edit that element. */ if ( _offByHotkey ) { cvg_getFld ( &cur_el, TAG_GFA_SUBTYPE, value, &ier ); subtyp = atoi ( value ); cvg_getFld ( &cur_el, TAG_GFA_AREATYPE, value, &ier ); areatyp = atoi ( value ); cvg_getFld ( &cur_el, TAG_GFA_TAG, tag, &ier ); cvg_scangfa ( NULL, pglayer_getCurLayer(), subtyp, areatyp, tag, &newel, &newel_loc, &ier ); if ( ier == 0 ) { crg_getinx ( cur_loc, &num, &ier); pghdlb_deselectEl ( num, TRUE ); pgactv_setActvElm ( &newel, newel_loc ); pghdlb_select ( &newel, newel_loc ); if( gfaIsUp ) { pggfaw_setAttr ( &newel ); } else { pggfawp_setAttr ( &newel ); } } else { pgevt_unsetOper ( TRUE ); } } else { pgevt_unsetOper ( TRUE ); } _offByHotkey = False; } } /* End "if" in edit mode */ } cvg_freeElPtr( &cur_el ); _fromGfa = False; }
/* ARGSUSED */ static void _pgmvcp_groupDropEh ( Widget w, XtPointer clnt, XEvent *event, Boolean *ctdr ) /************************************************************************ * _pgmvcp_groupDropEh * * * * This function is the callback for a drop on a group. * * * * static void _pgmvcp_groupDropEh (w, clnt, event, ctdr) * * * * Input parameters: * * w Widget Parent widget * * clnt XtPointer State information record * * *event XEvent Button press event record * * * ** * * Log: * * E. Safford/GSC 06/97 Modified to handle Special Text * * E. Wehner/EAi 07/97 Remove offsets when replacing text. * * E. Safford/GSC 07/97 Fixed drag with special text problem * * E. Wehner/EAi 08/97 Remove watch box slide * * C. Lin/EAI 8/97 Add offsets for 'S' coord(roam) * * D.W.Plummer/NCEP 9/97 Combine into NxmDraw for new vgstruct.h * * E. Wehner/EAi 9/97 Remove graphics info record * * C. Lin/EAi 10/97 rename from NxmDrSlDropCb, cleanup * * C. Lin/EAi 10/97 add WBOX_ELEM related functions * * C. Lin/EAi 11/97 further cleanup * * E. Safford/GSC 02/98 add _storedEl for undo function * * S. Law/GSC 04/98 added copy function * * E. Safford/GSC 04/98 added FUNC_SELECT to FUNC_MOVE ops * * S. Law/GSC 05/98 cleaned up drag, added group box * * E. Safford/GSC 05/98 mod for new undo routines * * E. Safford/GSC 05/98 move to nmap_pgmvcp.c * * E. Safford/GSC 06/98 split from mvcpDrop.c * * E. Safford/GSC 06/98 added call to cgr_grfrsh.c * * G. Krueger/EAI 06/98 Uniform status hints * * C. Lin/EAI 08/98 fix ghosting problem & reset _dragCount * * G. Krueger/EAI 09/98 Added ghost veiling * * G. Krueger/EAI 10/98 Using table for hints * * E. Safford/GSC 12/98 modify refresh to limit area affected * * D.W.Plummer/NCEP 4/99 remove call to pgwlst_update * * E. Safford/GSC 10/99 update for new xwcmn.h * * S. Law/GSC 06/00 changed to use xgtoff * * H. Zeng/EAI 11/00 changed for the new undo design * * H. Zeng/EAI 11/00 changed cvg_rdrec() parameters * * A. Hardy/GSC 11/00 renamed coordinate system declarations * * H. Zeng/EAI 12/00 modified for multiple undo steps * * J. Wu/SAIC 12/01 add layer in crg_set() call * * T. Lee/SAIC 11/03 added user directory to work_file * * T. Lee/SAIC 11/03 used cvg_getworkfile * * J. Wu/SAIC 11/03 adjust jet barb/hash position * * J. Wu/SAIC 02/04 adjust gfa attribute box position * * J. Wu/SAIC 10/04 free GFA block memory * * S. Danz/AWC 07/06 Added new cvg_delet placement argument * * S. Danz/AWC 08/06 New flag to pgvgf_saveNewElm to place el* * S. Danz/AWC 08/06 Updated to use cvg_checkplace to find * * area impacted and call crg_rebuild() * ***********************************************************************/ { int location, ier, nelm, ii, jj, *inxarry, layer, update_crg; int currfunc, newnum, old_location, xoff, yoff, found; float llx, lly, urx, ury, delx, dely; float o_llx, o_lly, o_urx, o_ury, inf_bbox[4]; char newtyp; VG_DBStruct el, del_el; /*---------------------------------------------------------------------*/ _dragCount = 0; mcanvw_disarmDrag(); mcanvw_disarmDrop(); pggst_clearGhost(TRUE); if (!_midDrag) return; _midDrag = FALSE; update_crg = 0; currfunc = pgpalw_getCurOperId(); old_location = pgactv_getElmLoc(); cvg_rdrec(cvg_getworkfile(), old_location, &el, &ier); crg_ggnel(el.hdr.grptyp, el.hdr.grpnum, &nelm, &ier); if (nelm <= 0) return; inxarry = (int *)malloc(nelm*sizeof(int)); crg_gginx (el.hdr.grptyp, el.hdr.grpnum, nelm, inxarry, &nelm, &ier); newtyp = el.hdr.grptyp; newnum = el.hdr.grpnum; crg_ggbnd (newtyp, newnum, &o_llx, &o_urx, &o_ury, &o_lly, &ier); if (currfunc == FUNC_COPY) crg_ggnxt (el.hdr.grptyp, &newnum, &ier); /* * set "delta" amounts... */ xgtoff (&xoff, &yoff, &ier); delx = (float)event->xbutton.x + (float)xoff - _dragX; dely = (float)event->xbutton.y + (float)yoff - _dragY; _dragX += delx; _dragY += dely; delx = _dragX - _origX - _goffX; dely = _dragY - _origY - _goffY; pghdlb_deselectEl (old_location, FALSE); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } pgundo_newStep(); layer = pglayer_getCurLayer( ); for (ii = 0; ii < nelm; ii++) { crg_goffset(inxarry[ii], &location, &ier); cvg_rdrec(cvg_getworkfile(), location, &el, &ier); pgactv_setActvElm ( &el, location); pgactv_getDevPts (&_dcN, &_dcX, &_dcY); for (jj = 0; jj < _dcN; jj++) { pgactv_modPt (jj, *(_dcX + jj) + delx, *(_dcY + jj) + dely); } if ((currfunc == FUNC_MOVE) || (currfunc == FUNC_SELECT)) { /* * Mark elements in placement that are effected by * the delete, and get the area of influence back */ cvg_rdrec(cvg_getworkfile(), location, &del_el, &ier); cvg_checkplace(&del_el, 1, location, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by * placement was bigger than the area passed in */ o_llx = G_MIN(o_llx, inf_bbox[0]); o_lly = G_MIN(o_lly, inf_bbox[2]); o_urx = G_MAX(o_urx, inf_bbox[1]); o_ury = G_MAX(o_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( del_el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &del_el ); } else if ( del_el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &del_el ); } /* * delete old element */ cvg_delet (cvg_getworkfile(), location, TRUE, &ier); crg_clear (inxarry[ii], &ier); pgundo_storeThisLoc(location, UNDO_DEL, &ier); } /* * adjust jet barb/hash position accordingly */ if ( el.hdr.vg_type == JET_ELM ) { _pgmvcp_jetCalc ( &el, delx, dely, True ); } /* * adjust GFA attribute box position accordingly */ if ( el.hdr.vg_type == GFA_ELM ) { _pgmvcp_gfaCalc ( &el, delx, dely, True ); } /* * save new element */ el.hdr.grptyp = newtyp; el.hdr.grpnum = newnum; pgvgf_saveNewElm(NULL, sys_D, &el, _dcN, _dcX, _dcY, FALSE, &location, &ier); pgundo_storeThisLoc (location, UNDO_ADD, &ier); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } cvg_rdrec(cvg_getworkfile(), location, &el, &ier); crg_set (&el, location, layer, &ier); /* * Mark elements in placement that are effected by * the new element, and get the area of influence back */ cvg_checkplace(&el, 0, location, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by * placement was bigger than the area passed in */ o_llx = G_MIN(o_llx, inf_bbox[0]); o_lly = G_MIN(o_lly, inf_bbox[2]); o_urx = G_MAX(o_urx, inf_bbox[1]); o_ury = G_MAX(o_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } } /* for */ pgundo_endStep(); pgactv_setActvElm (&el, location); crg_ggbnd (newtyp, newnum, &llx, &urx, &ury, &lly, &ier); free (inxarry); o_llx -= EXTRA; o_lly -= EXTRA; o_urx += EXTRA; o_ury += EXTRA; if (o_llx < llx) llx = o_llx; if (o_lly < lly) lly = o_lly; if (o_urx > urx) urx = o_urx; if (o_ury > ury) ury = o_ury; xpgpaste (llx, lly, urx, ury, &ier); cvg_rfrsh (NULL, llx, lly, urx, ury, &ier); /* * If we may have impacted other elements with placement * we will need to rebuild the range records */ if (update_crg) { crg_rebuild(); } pghdlb_select (&el, location); mbotw_mouseSet(LMHINT_DRAG, MMHINT_DONE); }
void pggrpch_chngGrp ( void ) /************************************************************************ * pggrpch_chngGrp * * * * Change the group type of the elements according to instructions on * * VG Group Change Window. * * * * void pggrpch_chngGrp () * * * * Input parameters: * * Output parameters: * * Return: * * NONE * * * ** * * Log: * * H. Zeng/EAI 05/01 initial coding * * J. Wu/SAIC 12/01 add layer in crg_set() call * * J. Wu/SAIC 01/02 change only groups on current layer * * H. Zeng/EAI 03/02 renamed for new nmap_pggrpch file * * H. Zeng/EAI 05/02 modified to use master group type list * * T. Lee/SAIC 11/03 added user directory to work_file * * T. Lee/SAIC 11/03 used cvg_getworkfile * * J. Wu/SAIC 07/04 add filter param to crg_get * * B. Yin/SAIC 08/04 added code to free TCA memory * * B. Yin/SAIC 08/04 changed pgtca_freeBkpts to cvg_freeBkpts* * J. Wu/SAIC 10/04 free GFA block memory * * S. Danz/AWC 07/06 Added new cvg_delet placement argument * * S. Danz/AWC 08/06 New flag to pgvgf_saveNewElm to place el* * S. Danz/AWC 08/06 Updated to use cvg_checkplace to find * * area impacted and call crg_rebuild() * ***********************************************************************/ { int el_num, new_num, el_loc, extra = 5, dest_grpnum; int ori_grpnum, ier2, elN, new_location, ii, selection, iret; int grpid, cur_layer, el_layer, pl_found, update_crg; float llx, lly, urx, ury, m_llx, m_lly, m_urx, m_ury; float *elX, *elY, inf_bbox[4]; char ori_grptyp, dest_grptyp, ori_grpnam[20], dest_grpnam[20]; Boolean found; VG_DBStruct el; struct convertTblStrc *convert_tbl, *ptr, *ptr_prev; filter_t filter; /*---------------------------------------------------------------------*/ m_llx = 999999.0F; m_lly = 999999.0F; m_urx = 0.0F; m_ury = 0.0F; convert_tbl = NULL; ptr = NULL; ptr_prev = NULL; update_crg = 0; pgundo_newStep(); cur_layer = pglayer_getCurLayer( ); for (el_num = 0; el_num < MAX_EDITABLE_ELEMS; el_num++) { crg_goffset (el_num, &el_loc, &ier2); el_layer = crg_getLayer ( el_loc ); /* * Skip cleared range record or those not on current layer. */ if (el_loc == -1 || el_layer != cur_layer) { continue; } crg_ggrp (el_num, &ori_grptyp, &ori_grpnum, &ier2); if (ori_grpnum && ori_grptyp != GRPTYP_OTHERS && ori_grptyp != GRPTYP_COMSYM && ori_grptyp != GRPTYP_WATCH && ori_grptyp != GRPTYP_CCF ) { ces_gtgnam((int)ori_grptyp, ori_grpnam, &ier2); for( ii = 0; ii < _numCurGrp; ii++ ) { if(strcmp(_curGrpStr[ii], ori_grpnam) == 0) { selection = ii + 1; break; } } if(ii < _numCurGrp && _chngToStrc.chng_flag[selection] == TRUE) { strcpy(dest_grpnam, _chngToStr[ _chngToStrc.current[selection]-1 ]); ces_gtgid(dest_grpnam, &grpid, &ier2); dest_grptyp = (char)grpid; /* Search on conversion table to see if there is entry * that has the same ori_grptyp, ori_grpnum and dest_grptyp. * If yes, get dest_grpnum from there. */ found = FALSE; ptr = convert_tbl; while(ptr != NULL) { if(ori_grptyp == ptr->ori_grptyp && dest_grptyp== ptr->dest_grptyp&& ori_grpnum == ptr->ori_grpnum ) { dest_grpnum = ptr->dest_grpnum; found = TRUE; break; } ptr = ptr->next; } /* * If not found on conversion table, get next available * group number. Add new entry into conversion table. */ if(!found) { crg_ggnxt(dest_grptyp, &dest_grpnum, &ier2); if(convert_tbl == NULL) { convert_tbl = (struct convertTblStrc*)malloc( sizeof(struct convertTblStrc) ); convert_tbl->ori_grptyp = ori_grptyp; convert_tbl->dest_grptyp= dest_grptyp; convert_tbl->ori_grpnum = ori_grpnum; convert_tbl->dest_grpnum= dest_grpnum; convert_tbl->next = NULL; convert_tbl->prev = NULL; } else { ptr = convert_tbl; while(ptr->next != NULL) ptr = ptr->next; ptr->next = (struct convertTblStrc*)malloc( sizeof(struct convertTblStrc) ); ptr_prev = ptr; ptr = ptr->next; ptr->ori_grptyp = ori_grptyp; ptr->dest_grptyp= dest_grptyp; ptr->ori_grpnum = ori_grpnum; ptr->dest_grpnum= dest_grpnum; ptr->next = NULL; ptr->prev = ptr_prev; } } /* the end of if(!found... */ cvg_rdrec (cvg_getworkfile(), el_loc, &el, &ier2); /* * Create a copy of the element with new group info, */ pgactv_setActvElm ( &el, el_loc); pgactv_getDevPts (&elN, &elX, &elY); pgvgf_saveNewElm(NULL, sys_D, &el, elN, elX, elY, FALSE, &new_location, &iret); cvg_setginf(cvg_getworkfile(), new_location, dest_grptyp, dest_grpnum, &iret); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } cvg_rdrec(cvg_getworkfile(), new_location, &el, &iret); crg_set (&el, new_location, cur_layer, &iret); crg_getinx (new_location, &new_num, &iret); crg_get(new_num, &el_layer, filter, &llx, &lly, &urx, &ury, &iret); if (m_llx > llx) m_llx = llx; if (m_lly > lly) m_lly = lly; if (m_urx < urx) m_urx = urx; if (m_ury < ury) m_ury = ury; /* * Mark elements in placement that are effected by * the new element, and get the area of influence back */ cvg_checkplace(&el, 0, new_location, &pl_found, inf_bbox, &iret); if (pl_found > 0) { /* * Update the refresh extent if the area impacted by * placement is bigger */ m_llx = G_MIN(m_llx, inf_bbox[0]); m_lly = G_MIN(m_lly, inf_bbox[2]); m_urx = G_MAX(m_urx, inf_bbox[1]); m_ury = G_MAX(m_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } pgundo_storeThisLoc(new_location, UNDO_ADD, &iret); /* * Mark elements in placement that are effected by * the delete, and get the area of influence back */ cvg_rdrec(cvg_getworkfile(), el_loc, &el, &iret); cvg_checkplace(&el, 1, el_loc, &pl_found, inf_bbox, &iret); if (pl_found > 0) { /* * Update the refresh extent if the area impacted by * placement is bigger */ m_llx = G_MIN(m_llx, inf_bbox[0]); m_lly = G_MIN(m_lly, inf_bbox[2]); m_urx = G_MAX(m_urx, inf_bbox[1]); m_ury = G_MAX(m_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } /* * Mark the original element as deleted. */ cvg_delet(cvg_getworkfile(), el_loc, TRUE, &ier2); crg_get (el_num, &el_layer, filter, &llx, &lly, &urx, &ury, &ier2); if (m_llx > llx) m_llx = llx; if (m_lly > lly) m_lly = lly; if (m_urx < urx) m_urx = urx; if (m_ury < ury) m_ury = ury; crg_clear(el_num, &ier2); pgundo_storeThisLoc (el_loc, UNDO_DEL, &ier2); } /* the end of if(ii < _numCurGrp ... ) */ } /* the end of if (ori_grpnum &&... */ } /* for (el_num = 0 ... */ pgundo_endStep(); m_llx -= (float)extra; m_lly -= (float)extra; m_urx += (float)extra; m_ury += (float)extra; xpgpaste (m_llx, m_lly, m_urx, m_ury, &ier2); cvg_rfrsh (NULL, m_llx, m_lly, m_urx, m_ury, &ier2); /* * If we may have impacted other elements with placement * we will need to rebuild the range records */ if (update_crg) { crg_rebuild(); } /* * Free conversion table */ if(convert_tbl != NULL) { ptr = convert_tbl; while(ptr->next != NULL) ptr = ptr->next; do { ptr_prev = ptr->prev; free(ptr); ptr = ptr_prev; } while(ptr != NULL); } }
/* ARGSUSED */ static void _pgmvcp_elDropEh ( Widget w, XtPointer clnt, XEvent *event, Boolean *ctdr ) /************************************************************************ * _pgmvcp_elDropEh * * * * This function is the callback for a drop on a selected element. * * * * static void _pgmvcp_elDropEh (w, clnt, event, ctdr) * * * * Input parameters: * * w Widget Parent widget * * clnt XtPointer State information record * * *event XEvent Button press event record * * * ** * * Log: * * E. Safford/GSC 06/97 Modified to handle Special Text * * E. Wehner/EAi 07/97 Remove offsets when replacing text. * * E. Safford/GSC 07/97 Fixed drag with special text problem * * E. Wehner/EAi 08/97 Remove watch box slide * * C. Lin/EAI 8/97 Add offsets for 'S' coord(roam) * * D.W.Plummer/NCEP 9/97 Combine into NxmDraw for new vgstruct.h * * E. Wehner/EAi 9/97 Remove graphics info record * * C. Lin/EAi 10/97 rename from NxmDrSlDropCb, cleanup * * C. Lin/EAi 10/97 add WBOX_ELEM related functions * * C. Lin/EAi 11/97 further cleanup * * E. Safford/GSC 02/98 add _storedEl for undo function * * S. Law/GSC 04/98 added copy function * * E. Safford/GSC 04/98 added FUNC_SELECT to FUNC_MOVE ops * * S. Law/GSC 05/98 cleaned up drag, added group box * * E. Safford/GSC 05/98 mod for new undo routines * * E. Safford/GSC 05/98 move to nmap_pgmvcp.c * * E. Safford/GSC 06/98 split from mvcpDrop.c * * G. Krueger/EAI 06/98 Uniform status hints * * E. Safford/GSC 07/98 reset _dcN for closed figures * * C. Lin/EAI 08/98 fix ghosting problem & reset _dragCount * * G. Krueger/EAI 09/98 Added ghost veiling * * G. Krueger/EAI 10/98 Using table for hints * * E. Safford/GSC 12/98 modify refresh to limit area affected * * D.W.Plummer/NCEP 4/99 remove call to pgwlst_update * * E. Safford/GSC 11/00 wipe the county list for watches * * H. Zeng/EAI 11/00 changed for the new undo design * * H. Zeng/EAI 11/00 changed cvg_rdrec() parameters * * A. Hardy/GSC 11/00 renamed coordinate system declaration * * H. Zeng/EAI 12/00 modified for multiple undo steps * * J. Wu/SAIC 12/01 add layer in crg_set() call * * J. Wu/SAIC 01/02 add layer in crg_get() call * * T. Lee/SAIC 11/03 added user directory to work_file * * T. Lee/SAIC 11/03 used cvg_getworkfile * * J. Wu/SAIC 11/03 adjust jet barb/hash position * * J. Wu/SAIC 02/04 adjust gfa attribute box position * * J. Wu/SAIC 07/04 add filter param. to crg_get() * * J. Wu/SAIC 07/04 free GFA block memory * * B. Yin/SAIC 02/05 add a call to snap for GFA * * E. Safford/SAIC 06/05 allow smear to get smaller on edit * * S. Danz/AWC 07/06 Added new cvg_delet placement argument * * S. Danz/AWC 08/06 New flag to pgvgf_saveNewElm to place el* * S. Danz/AWC 08/06 Updated to use cvg_checkplace to find * * area impacted and call crg_rebuild() * * S. Danz/AWC 02/07 Add logic to update GFA centroid * * L. Hinson/AWC 07/09 Add code to update CCF centroid * ***********************************************************************/ { int location, ier, currfunc, new_location, num, layer, el_layer; int found, update_crg, one = 1; float llx, lly, urx, ury; float x_cntr, y_cntr, c_lat, c_lon, area; float o_llx, o_lly, o_urx, o_ury, inf_bbox[4]; char value[32]; VG_DBStruct el, del_el; filter_t filter; /*---------------------------------------------------------------------*/ _dragCount = 0; mcanvw_disarmDrag(); mcanvw_disarmDrop(); if ( _wboxElm ) { pgwpts_setSnap (TRUE); _pgmvcp_wboxCalc ( ); } pggst_clearGhost(TRUE); if (!_midDrag) return; _midDrag = FALSE; update_crg = 0; currfunc = pgpalw_getCurOperId(); pgundo_newStep(); location = pgactv_getElmLoc(); cvg_rdrec(cvg_getworkfile(), location, &el, &ier); crg_getinx (location, &num, &ier); crg_get (num, &el_layer, filter, &o_llx, &o_lly, &o_urx, &o_ury, &ier); pghdlb_deselectEl (location, FALSE); if ((currfunc == FUNC_MOVE) || (currfunc == FUNC_SELECT)) { /* * Mark elements in placement that are effected by * the delete, and get the area of influence back */ cvg_rdrec(cvg_getworkfile(), location, &del_el, &ier); cvg_checkplace(&del_el, 1, location, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by * placement was bigger than the area passed in */ o_llx = G_MIN(o_llx, inf_bbox[0]); o_lly = G_MIN(o_lly, inf_bbox[2]); o_urx = G_MAX(o_urx, inf_bbox[1]); o_ury = G_MAX(o_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( del_el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &del_el ); } else if ( del_el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &del_el ); } /* * delete old element */ cvg_delet (cvg_getworkfile(), location, TRUE, &ier); crg_clear (num, &ier); pgundo_storeThisLoc(location, UNDO_DEL, &ier); } if ( el.hdr.vg_type == WBOX_ELM ) { pgwbxw_getAnchor ( 0, el.elem.wbx.info.w_a0id, &el.elem.wbx.info.w_a0lt, &el.elem.wbx.info.w_a0ln, &el.elem.wbx.info.w_a0dis, el.elem.wbx.info.w_a0dir, &ier ); pgwbxw_getAnchor ( 1, el.elem.wbx.info.w_a1id, &el.elem.wbx.info.w_a1lt, &el.elem.wbx.info.w_a1ln, &el.elem.wbx.info.w_a1dis, el.elem.wbx.info.w_a1dir, &ier ); /* * Wipe the county list */ el.elem.wbx.info.numcnty = 0; } /* * adjust jet barb/hash position accordingly */ if ( el.hdr.vg_type == JET_ELM ) { _pgmvcp_jetCalc ( &el, 0, 0, False ); } if ( el.hdr.vg_type == SIGCCF_ELM ) { _pgmvcp_ccfCalc ( &el, 0, 0, False ); gtrans ( sys_D, sys_M, &_dcN, _dcX, _dcY, &(el.elem.ccf.latlon[0]), &(el.elem.ccf.latlon[_dcN]), &ier, strlen(sys_D), strlen(sys_M) ); _dcN = el.elem.ccf.info.npts; cvg_todev ( &el, &_dcN, _dcX, _dcY, &ier ); if ( el.hdr.closed ) { cgr_centroid ( _dcX, _dcY, &_dcN, &x_cntr, &y_cntr, &area, &ier ); } else { x_cntr = _dcX[0] ; y_cntr = _dcY[0] ; } gtrans( sys_D, sys_M, &one, &x_cntr, &y_cntr, &c_lat, &c_lon, &ier, strlen(sys_D), strlen(sys_M) ); el.elem.ccf.info.arrowlat = c_lat; el.elem.ccf.info.arrowlon = c_lon; } /* * adjust GFA attribute box position accordingly */ if ( el.hdr.vg_type == GFA_ELM ) { _pgmvcp_gfaCalc ( &el, 0, 0, False ); gtrans ( sys_D, sys_M, &_dcN, _dcX, _dcY, &(el.elem.gfa.latlon[0]), &(el.elem.gfa.latlon[_dcN]), &ier, strlen(sys_D), strlen(sys_M) ); pgsmear_snapEl ( FALSE, &el, &ier ); _dcN = el.elem.gfa.info.npts; cvg_todev( &el, &_dcN, _dcX, _dcY, &ier ); if ( pggfaw_isClosed() ) { cgr_centroid( _dcX, _dcY, &_dcN, &x_cntr, &y_cntr, &area, &ier ); } else { x_cntr = _dcX[ 0 ]; y_cntr = _dcY[ 0 ]; } gtrans( sys_D, sys_M, &one, &x_cntr, &y_cntr, &c_lat, &c_lon, &ier, strlen(sys_D), strlen(sys_M) ); sprintf ( value, "%7.2f", c_lat ); cvg_setFld ( &el, TAG_GFA_ARROW_LAT, value, &ier ); sprintf ( value, "%7.2f", c_lon ); cvg_setFld ( &el, TAG_GFA_ARROW_LON, value, &ier ); } /* * save new element */ pgvgf_saveNewElm(NULL, sys_D, &el, _dcN, _dcX, _dcY, FALSE, &new_location, &ier); pgundo_storeThisLoc (new_location, UNDO_ADD, &ier); pgundo_endStep(); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } cvg_rdrec(cvg_getworkfile(), new_location, &el, &ier); layer = pglayer_getCurLayer( ); crg_set (&el, new_location, layer, &ier); pgactv_setActvElm (&el, new_location); crg_getinx (new_location, &num, &ier); crg_get(num, &el_layer, filter, &llx, &lly, &urx, &ury, &ier); if (o_llx < llx) llx = o_llx; if (o_lly < lly) lly = o_lly; if (o_urx > urx) urx = o_urx; if (o_ury > ury) ury = o_ury; /* * Mark elements in placement that are effected by * the new element, and get the area of influence back */ cvg_checkplace(&el, 0, new_location, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by * placement was bigger than the area passed in */ llx = G_MIN(llx, inf_bbox[0]); lly = G_MIN(lly, inf_bbox[2]); urx = G_MAX(urx, inf_bbox[1]); ury = G_MAX(ury, inf_bbox[3]); update_crg = 1; } xpgpaste (llx, lly, urx, ury, &ier); cvg_rfrsh (NULL, llx, lly, urx, ury, &ier); /* * If we may have impacted other elements with placement * we will need to rebuild the range records */ if (update_crg) { crg_rebuild(); } pghdlb_select (&el, new_location); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } mbotw_mouseSet(LMHINT_DRAG, MMHINT_DONE); }
/* ARGSUSED */ static void pgconn_select ( Widget wid, XtPointer clnt, XEvent *event, Boolean *ctdr ) /************************************************************************ * pgconn_select * * * * This function handles the selection callbacks * * * * static void pgconn_select (wid, clnt, event, ctdr ) * * * * Input parameters: * * wid Widget calling widget * * clnt XtPointer * * *event XEvent * * * * Output parameters: * * NONE * * * ** * * Log: * * S. Law/GSC 09/98 Initial coding * * S. Law/GSC 09/98 Removed unnecessary refreshes * * E. Safford/GSC 09/98 fix ghost problem conn to 2 pt lines * * G. Krueger/EAI 10/98 Using table for mouse hints * * S. Law/GSC 09/98 added CLASS_SIGMETS * * S. Law/GSC 09/99 added parameter to mcanvw_set* functions* * E. Safford/GSC 10/99 update for new xwcmn.h * * S. Law/GSC 02/00 added CCF * * S. Law/GSC 03/00 added parameter to pgutls_prepNew * * H. Zeng/EAI 04/00 changed cursor name * * S. Law/GSC 06/00 changed to use xgtoff * * H. Zeng/EAI 11/00 modified for the new undo design * * A. Hardy/GSC 11/00 renamed coordinate system declaration * * H. Zeng/EAI 12/00 modified for multiple undo steps * * J. Wu/GSC 03/01 added "EXIT" hint to bottom panel * * J. Wu/SAIC 01/02 scan the current PGEN layer only * * E. Safford/SAIC 03/02 rename from _pgconn_select, add * * pgutls_regroup(), clean up * * E. Safford/SAIC 04/02 check ier from cvg_scan to avoid UMR * * T. Lee/SAIC 11/03 added user directory to work_file * * T. Lee/SAIC 11/03 used cvg_getworkfile * * S. Danz/AWC 08/06 New flag to pgvgf_saveNewElm to place el* * J. Wu/SAIC 06/07 connect GFAs * ***********************************************************************/ { float xx, yy, llx, lly, urx, ury; float *primary_x, *primary_y; float secondary_x[MAXPTS], secondary_y[MAXPTS]; int primary_n, primary_loc, secondary_n; int ier, near, test, xoff, yoff, cur_layer; int start, grp_num1, grp_num2; char grp_typ1, grp_typ2, warnMsg[256], value[10]; char mesg[] = {"Maximum vertices exceeded."}; Boolean primary_grouped = FALSE; Boolean secondary_grouped = FALSE; static int secondary_elnum; static int secondary_loc; static Boolean reverse_flag = FALSE; static VG_DBStruct secondary_el; static VG_DBStruct GFA_el; int GFA_pts, GFA_newloc; float GFA_x[MAXPTS], GFA_y[MAXPTS]; /*---------------------------------------------------------------------*/ xgtoff (&xoff, &yoff, &ier); cur_layer = pglayer_getCurLayer (); if (event->xbutton.button == Button1) { if (_selectFlag) { /* confirming secondary element */ grp_typ1 = _primaryEl.hdr.grptyp; grp_num1 = _primaryEl.hdr.grpnum; if ( grp_typ1 > 0 && grp_num1 > 0 ) { primary_grouped = TRUE; } cvg_todev (&secondary_el, &secondary_n, secondary_x, secondary_y, &ier); grp_typ2 = secondary_el.hdr.grptyp; grp_num2 = secondary_el.hdr.grpnum; if ( grp_typ2 > 0 && grp_num2 > 0 ) { secondary_grouped = TRUE; } if ( _drawGhost ) { near = pgactv_getNearPt (); pgactv_getDevPts (&primary_n, &primary_x, &primary_y); start = (FindNearEnd (0, near, (primary_n - 1)) == 0) ? 0 : primary_n; if (reverse_flag) { pgutls_fReverseArray (secondary_n, secondary_x, secondary_y); } pgactv_addPts (secondary_x, secondary_y, secondary_n, start, &ier); } if (ier == 0) { if ( _drawGhost ) { pgactv_getDevPts (&primary_n, &primary_x, &primary_y); } /* * Grouping the new element: * * If the primary element was grouped, the new element stays in * that group. If the primary element was not grouped, but the * secondary element was, then put the new element in the * secondary element's group. */ if ( !primary_grouped && secondary_grouped ) { _primaryEl.hdr.grptyp = grp_typ2; _primaryEl.hdr.grpnum = grp_num2; } /* * Save the new element: * * For non-GFAs or open FZLVLs, use points of both the primary * and secondary elements. * * For closed GFAs, use points resulting from smearing the primary * and secondary elements. * * Note: The new GFA element will use the the primary element's * forecast hour, color, and line attributes. */ if ( _drawGhost ) { pgundo_newStep(); pgundo_storeThisLoc ( _primaryLoc, UNDO_DEL, &ier ); pgundo_storeThisLoc ( secondary_loc, UNDO_DEL, &ier ); pgutls_prepNew ( -1, &_primaryEl, &llx, &lly, &urx, &ury, &ier); pgvgf_saveNewElm ( cvg_getworkfile(), sys_D, &_primaryEl, primary_n, primary_x, primary_y, TRUE, &primary_loc, &ier ); pgutls_redraw ( primary_loc, &_primaryEl, &ier ); pgundo_storeThisLoc ( primary_loc, UNDO_ADD, &ier); } else { pgvgf_saveNewElm ( cvg_getworkfile(), sys_M, &GFA_el, 0, GFA_x, GFA_y, TRUE, &GFA_newloc, &ier ); if ( ier >= 0 ) { pgundo_newStep(); pgundo_storeThisLoc ( _primaryLoc, UNDO_DEL, &ier ); pgundo_storeThisLoc ( secondary_loc, UNDO_DEL, &ier ); pgactv_setActvElm ( &_primaryEl, _primaryLoc ); pgutls_prepNew ( _primaryLoc, &_primaryEl, &llx, &lly, &urx, &ury, &ier); pgutls_redraw ( GFA_newloc, &GFA_el, &ier ); pgundo_storeThisLoc ( GFA_newloc, UNDO_ADD, &ier ); } else if ( ier == -28 ) { /* too few points in resulting smear */ cvg_getFld ( &GFA_el, TAG_GFA_TAG, value, &ier ); sprintf( warnMsg, "Unable to connect tag %s.\n It has too few points after smearing and/or snapping.\n", value ); NxmWarn_show( mcanvw_getDrawingW(), warnMsg ); } cvg_freeElPtr ( &GFA_el ); } /* * set the secondary element as the active * one, so that prepNew can remove it */ pgactv_setActvElm (&secondary_el, secondary_loc); pgutls_prepNew (secondary_loc, &secondary_el, &llx, &lly, &urx, &ury, &ier); /* * If both elements were grouped, then move all elements * grouped with the secondary element into the primary * element's group. */ if ( primary_grouped && secondary_grouped ) { pgutls_regroup ( grp_typ2, grp_num2, grp_typ1, grp_num1, &ier ); } pgundo_endStep(); /* * Clean up for next connection. */ if ( _isGFA ) { cvg_freeElPtr ( &secondary_el ); cvg_freeElPtr ( &_primaryEl ); } pghdlb_deselectAll (); pgactv_clearActv (); pggst_clearGhost ( FALSE ); } else { NxmWarn_show (wid, mesg); } mcanvw_setPressFunc ((XtEventHandler)&pgevt_locateElmCb, CURS_DEFAULT); if ( _drawGhost ) mcanvw_disarmDrag (); _selectFlag = FALSE; mbotw_mouseSet(LMHINT_SELECT, MMHINT_EXIT); } else { /* selecting secondary element */ xx = (float) (event->xbutton.x + xoff); yy = (float) (event->xbutton.y + yoff); test = False; cvg_scan (NULL, cur_layer, (char)_primaryEl.hdr.vg_class, xx, yy, 0, &secondary_el, &secondary_loc, &near, &ier); /* * Verify elements only if no error returned from cvg_scan. */ if ( ier >= 0 ) { test = pgconn_verifyType ( &_primaryEl, &secondary_el); } /* * Verify there are actually 2 elements, not the same element. */ if (test) { if (secondary_loc == pgactv_getElmLoc () || secondary_loc == 0) { test = FALSE; } } if ( test ) { crg_getinx ( secondary_loc, &secondary_elnum, &ier ); /* * Get the points for the potential connect/join and use it * to draw the ghost line so the user can have a feel of the * result before making the confirmation. * * For non-GFAs or open FZLVLs, connect points of both the primary * and secondary elements. * * For closed GFAs, get points by smearing the primary and * secondary elements. * */ if ( !_drawGhost ) { /* * Select the second GFA. */ pghdlb_select ( &secondary_el, secondary_loc ); /* * Smear two GFA polygons. */ GFA_pts = 0; GFA_el.elem.gfa.info.nblocks = 0; pgconn_smear ( _primaryLoc, secondary_loc, &GFA_el, &GFA_pts, GFA_x, GFA_y ); /* * Ghost the resulting polygon. */ pggst_clearGhost (TRUE); pggst_setLineAttr ( _primaryEl.hdr.smooth, (Boolean)_primaryEl.hdr.closed ); pggst_addGhostPts ( GFA_pts, GFA_x, GFA_y, &ier ); pggst_drawGhost ( GST_NORMAL ); } else { pggst_drawGhost (GST_NORMAL); mcanvw_disarmDrag (); cvg_todev (&secondary_el, &secondary_n, secondary_x, secondary_y, &ier); if (FindNearEnd (0, near, (secondary_n - 1))) { reverse_flag = TRUE; pgutls_fReverseArray (secondary_n, secondary_x, secondary_y); } else { reverse_flag = FALSE; } pggst_replaceGhostPts (1, &secondary_x[0], &secondary_y[0], &ier); pggst_addGhostPts ((secondary_n - 1), &secondary_x[1], &secondary_y[1], &ier); pggst_drawGhost (GST_NORMAL); } _selectFlag = TRUE; mbotw_mouseSet(LMHINT_CONFIRM, MMHINT_CANCEL); } } } else { if (_selectFlag) { /* unselecting secondary element */ pghdlb_deselectEl ( secondary_elnum, TRUE ); pghdlb_displayAllSel (); if ( _drawGhost ) { xx = (float) (event->xbutton.x + xoff); yy = (float) (event->xbutton.y + yoff); _ghostX[_ghostN] = xx; _ghostY[_ghostN] = yy; pggst_clearGhost (FALSE); pggst_addGhostPts ((_ghostN + 1), _ghostX, _ghostY, &ier); pggst_drawGhost (GST_NORMAL); } _selectFlag = FALSE; mbotw_mouseSet(LMHINT_NEXT, MMHINT_DONE); if ( _drawGhost ) { mcanvw_setDragFunc((XtEventHandler)&pgconn_ghost, CURS_DEFAULT); } if ( _isGFA ) { cvg_freeElPtr ( &secondary_el ); if ( !_drawGhost ) cvg_freeElPtr ( &GFA_el ); } } else { /* unselecting primary element */ if ( _isGFA ) { cvg_freeElPtr ( &_primaryEl ); } mcanvw_disarmDynamic (); _selectFlag = FALSE; pghdlb_deselectAll(); mcanvw_setPressFunc ((XtEventHandler)&pgevt_locateElmCb, CURS_DEFAULT); _selectFlag = FALSE; mbotw_mouseSet(LMHINT_SELECT, MMHINT_EXIT); } } }