Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

plug_tag.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002    Major portions of this software are copyrighted by the Medical College
00003    of Wisconsin, 1994-2000, and are released under the Gnu General Public
00004    License, Version 2.  See the file README.Copyright for details.
00005 ******************************************************************************/
00006 
00007 #undef MAIN
00008 #include "afni.h"
00009 #include <ctype.h>
00010 
00011 #ifndef ALLOW_PLUGINS
00012 #  error "Plugins not properly set up -- see machdep.h"
00013 #endif
00014 
00015 /*-- prototypes --*/
00016 
00017 static char * TAG_main( PLUGIN_interface * ) ;
00018 
00019 static void TAG_make_widgets(void) ;
00020 
00021 static void TAG_dset_CB    ( Widget , XtPointer , XtPointer ) ;
00022 static void TAG_quit_CB    ( Widget , XtPointer , XtPointer ) ;
00023 static void TAG_help_CB    ( Widget , XtPointer , XtPointer ) ;
00024 static void TAG_set_CB     ( Widget , XtPointer , XtPointer ) ;
00025 static void TAG_clear_CB   ( Widget , XtPointer , XtPointer ) ;
00026 static void TAG_done_CB    ( Widget , XtPointer , XtPointer ) ;
00027 static void TAG_tog_CB     ( Widget , XtPointer , XtPointer ) ;
00028 static void TAG_read_CB    ( Widget , XtPointer , XtPointer ) ;
00029 static void TAG_write_CB   ( Widget , XtPointer , XtPointer ) ;
00030 static void TAG_copy_CB    ( Widget , XtPointer , XtPointer ) ;
00031 static void TAG_save_CB    ( Widget , XtPointer , XtPointer ) ;
00032 static void TAG_clearall_CB( Widget , XtPointer , XtPointer ) ;
00033 static void TAG_add_CB     ( Widget , XtPointer , XtPointer ) ;
00034 static void TAG_delete_CB  ( Widget , XtPointer , XtPointer ) ;
00035 static void TAG_relabel_CB ( Widget , XtPointer , XtPointer ) ;
00036 static void TAG_beep_CB    ( Widget , XtPointer , XtPointer ) ;
00037 
00038 static void TAG_value_CB ( MCW_arrowval * , XtPointer ) ;
00039 static void TAG_columnize(void) ;
00040 static void TAG_reset_widgets(void) ;
00041 
00042 static void TAG_onoff( int ) ;
00043 
00044 /*-- Widgets for the user interface --*/
00045 
00046 static Widget shell=NULL , thetop ;
00047 static Widget dset_pb , info_lab ;
00048 static Widget quit_pb, help_pb, read_pb, write_pb, copy_pb, save_pb, done_pb ;
00049 static Widget set_pb, clear_pb, clearall_pb, add_pb, delete_pb, relabel_pb, beep_pb ;
00050 static Widget scrollw, wframe, workwin ;
00051 static Widget actar ;
00052 
00053 static Widget * tagtog ;      /* one for each possible tag */
00054 static int    * toginv ;
00055 static int      tognum = 4 ;  /* default number of active toggles */
00056 
00057 static THD_usertaglist * mytagset  = NULL ;  /* what we are working on */
00058 static THD_usertaglist * oldtagset = NULL ;  /* in case of Quit */
00059 
00060 static PLUGIN_strval * file_strav ;
00061 static PLUGIN_strval * label_strav ;
00062 static MCW_arrowval  * value_av ;
00063 
00064 #define DEFAULT_INFOLAB "[No dataset has yet been selected]"
00065 
00066 static int      on_flag = 0 ;
00067 static Widget * onoff_wid[] = {
00068    &read_pb , &write_pb , &copy_pb     , &save_pb , &done_pb   ,
00069    &set_pb  , &clear_pb , &clearall_pb ,
00070    NULL } ;
00071 
00072 #define DSET_ON  SENSITIZE(dset_pb,True)
00073 #define DSET_OFF do{ if( dset != NULL ) SENSITIZE(dset_pb,False) ; } while(0)
00074 
00075 #define POPUP_MESG(mm) MCW_popup_message(save_pb,(mm),MCW_USER_KILL|MCW_TIMER_KILL)
00076 
00077 /*-- Other Data --*/
00078 
00079 static PLUGIN_interface * plint = NULL ;
00080 
00081 static int   value_int   = 0 ;    /* from value_av */
00082 static float value_float = 0.0 ;  /* ditto         */
00083 static int   active_tog  = -1 ;   /* active toggle index */
00084 
00085 static int   editor_open = 0 ;    /* is the editor already on screen? */
00086 
00087 static MCW_DC * dc ;
00088 static Three_D_View * im3d ;
00089 static THD_3dim_dataset * dset = NULL ;
00090 
00091 /***********************************************************************
00092    Set up the interface to the user.  Note that we bypass the
00093    normal interface creation, and simply have the menu selection
00094    directly call the main function, which will create a custom
00095    set of interface widgets.
00096 ************************************************************************/
00097 
00098 
00099 DEFINE_PLUGIN_PROTOTYPE
00100 
00101 PLUGIN_interface * PLUGIN_init( int ncall )
00102 {
00103    if( ncall > 0 ) return NULL ;  /* only one interface */
00104 
00105    plint = PLUTO_new_interface( "Edit Tagset" , NULL , NULL ,
00106                                 PLUGIN_CALL_IMMEDIATELY , TAG_main ) ;
00107 
00108    PLUTO_add_hint( plint , "Interactive Tagset Editor" ) ;
00109 
00110    PLUTO_set_sequence( plint , "A:misc" ) ;
00111    return plint ;
00112 }
00113 
00114 /*--------------------------------------------------------------------------*/
00115 
00116 static char * TAG_main( PLUGIN_interface * plint )
00117 {
00118    int ii ;
00119    XmString xstr ;
00120 
00121    /*-- sanity checks --*/
00122 
00123    if( ! IM3D_OPEN(plint->im3d) ) return "AFNI Controller\nnot opened?!" ;
00124 
00125    if( editor_open ){
00126       XtMapWidget(shell) ;
00127       XRaiseWindow( XtDisplay(shell) , XtWindow(shell) ) ;
00128       return NULL ;
00129    }
00130 
00131    im3d = plint->im3d ;  /* save for local use */
00132 
00133    /*-- create widgets, first time through --*/
00134 
00135    if( shell == NULL ){
00136       dc = im3d->dc ;        /* save this too */
00137       if( mytagset  == NULL ) mytagset  = myXtNew(THD_usertaglist) ;
00138       if( oldtagset == NULL ) oldtagset = myXtNew(THD_usertaglist) ;
00139       TAG_make_widgets() ;
00140       PLUTO_set_topshell( plint , shell ) ;  /* 22 Sep 2000 */
00141       RWC_visibilize_widget( shell ) ;       /* 27 Sep 2000 */
00142    }
00143 
00144    /*-- set titlebar --*/
00145 
00146    { char ttl[PLUGIN_STRING_SIZE] ;
00147      sprintf( ttl , "Tagset Editor %s" , AFNI_controller_label(im3d) ) ;
00148      XtVaSetValues( shell , XmNtitle , ttl , NULL ) ;
00149    }
00150 
00151    /*-- reset the info label --*/
00152 
00153    xstr = XmStringCreateLtoR( DEFAULT_INFOLAB , XmFONTLIST_DEFAULT_TAG ) ;
00154    XtVaSetValues( info_lab , XmNlabelString , xstr , NULL ) ;
00155    XmStringFree(xstr) ;
00156 
00157    /*-- pop the widgets up --*/
00158 
00159    TAG_onoff(0) ;                 /* widgets off until a dataset is selected */
00160    DSET_ON ;
00161    SENSITIZE(beep_pb,True) ;
00162    tognum = mytagset->num ;
00163    TAG_reset_widgets() ;
00164 
00165    XtMapWidget(shell) ;
00166    PLUTO_cursorize(shell) ;
00167 
00168    /*-- misc initialization --*/
00169 
00170    dset         = NULL ;   /* not editing anything   */
00171    editor_open  = 1 ;      /* editor is now open for business */
00172 
00173    active_tog = -1 ;
00174    for( ii=0 ; ii < tognum ; ii++ ){
00175       if( XmToggleButtonGetState( tagtog[ii] ) ){ active_tog = ii; break; }
00176    }
00177 
00178    oldtagset->num = 0 ;
00179    return NULL ;
00180 }
00181 
00182 /*--------------------------------------------------------------------------
00183      Make the plugin user interface
00184 ----------------------------------------------------------------------------*/
00185 
00186 /*-- structures defining 1st set of action buttons --*/
00187 
00188 #define NACT1 7  /* number of action buttons */
00189 
00190 static MCW_action_item TAG_actor1[NACT1] = {
00191  {"Quit",TAG_quit_CB,NULL,
00192   "Discard changes\nand close Tag plugin" ,
00193    "Discard changes & close",0} ,
00194 
00195  {"Help",TAG_help_CB,NULL,
00196   "Displays more help" , "Displays more help",0} ,
00197 
00198  {"Read",TAG_read_CB,NULL,
00199   "Read a tagset from disk" , "Read tagset from disk",0} ,
00200 
00201  {"Write",TAG_write_CB,NULL,
00202   "Write the tagset to disk" , "Write tagset to disk",0} ,
00203 
00204  {"Copy",TAG_copy_CB,NULL,
00205   "Copy tagset from another dataset" , "Copy from another dataset",0} ,
00206 
00207  {"Save",TAG_save_CB,NULL,
00208   "Save tagset in dataset header" , "Save tagset in dataset header",0} ,
00209 
00210  {"Done",TAG_done_CB,NULL,
00211   "Save changes in dataset\nand close Tag plugin" , "Save and close",1}
00212 } ;
00213 
00214 /*-- structures defining 2nd set of action buttons --*/
00215 
00216 #define NACT2 7  /* number of action buttons */
00217 
00218 static MCW_action_item TAG_actor2[NACT2] = {
00219 
00220  {"Set",TAG_set_CB,NULL,
00221   "Set the selected tag at the\ncurrent crosshair location" ,
00222   "Sets selected tag" , 0 } ,
00223 
00224  {"Clear",TAG_clear_CB,NULL,
00225   "Clears the selected tag\n(opposite of Set)" ,
00226   "Clears selected tag" , 0 } ,
00227 
00228  {"Clr All",TAG_clearall_CB,NULL,
00229   "Clears all tags (opposite of Set)" ,
00230   "Clears all tags" , 0 } ,
00231 
00232  {"Add",TAG_add_CB,NULL,
00233   "Add a new tag at\nthe end of list" ,
00234   "Add new tag at end" , 0 } ,
00235 
00236  {"Delete",TAG_delete_CB,NULL,
00237   "Remove the last\ntag from the list" ,
00238   "Remove last tag" , 0 } ,
00239 
00240  {"Relabel",TAG_relabel_CB,NULL,
00241   "Changes label of selected tag;\nUse after editing Tag Label\nstring field below",
00242   "Changes label of selected tag", 0 } ,
00243 
00244  {"Beep",TAG_beep_CB,NULL, NULL , NULL , 0 }
00245 } ;
00246 
00247 /*--------------------------------------------------------------------------*/
00248 
00249 static void TAG_make_widgets(void)
00250 {
00251    XmString xstr ;
00252    char tlab[MAX_TAG_LABEL] ;
00253    int ii , ww , hh ;
00254    Pixel  fg_pix ;
00255    Widget wjunk ;
00256 
00257    /*** top level shell for window manager ***/
00258 
00259    shell =
00260       XtVaAppCreateShell(
00261            "AFNI" , "AFNI" , topLevelShellWidgetClass , dc->display ,
00262 
00263            XmNtitle             , "AFNI Editor" , /* top of window */
00264            XmNiconName          , "Editor"      , /* label on icon */
00265            XmNdeleteResponse    , XmDO_NOTHING  , /* deletion handled below */
00266            XmNallowShellResize  , False ,         /* let code resize shell? */
00267            XmNmappedWhenManaged , False ,         /* must map it manually */
00268            XmNinitialResourcesPersistent , False ,
00269       NULL ) ;
00270 
00271    DC_yokify( shell , dc ) ;
00272 
00273    if( afni48_good )             /* set icon pixmap */
00274       XtVaSetValues( shell ,
00275                         XmNiconPixmap , afni48_pixmap ,
00276                      NULL ) ;
00277 
00278    if( MCW_isitmwm(shell) )      /* remove some MWM functions */
00279       XtVaSetValues( shell ,
00280                        XmNmwmFunctions , MWM_FUNC_MOVE     |
00281                                          MWM_FUNC_CLOSE    |
00282                                          MWM_FUNC_MINIMIZE |
00283                                          MWM_FUNC_RESIZE    ,
00284                      NULL ) ;
00285 
00286    XmAddWMProtocolCallback(      /* make "Close" window menu work */
00287            shell ,
00288            XmInternAtom( dc->display , "WM_DELETE_WINDOW" , False ) ,
00289            TAG_quit_CB , (XtPointer) plint ) ;
00290 
00291    /*** form widget to hold all user interface stuff ***/
00292 
00293    thetop = XtVaCreateWidget(
00294                  "AFNI" , xmFormWidgetClass , shell ,
00295                      XmNborderWidth , 0 ,
00296                      XmNborderColor , 0 ,
00297                      XmNtraversalOn , False ,
00298                      XmNinitialResourcesPersistent , False ,
00299                  NULL ) ;
00300 
00301    /*** pushbutton to select dataset for tagging ***/
00302 
00303    xstr = XmStringCreateLtoR( "Dataset" , XmFONTLIST_DEFAULT_TAG ) ;
00304    dset_pb =  XtVaCreateManagedWidget(
00305                 "AFNI" , xmPushButtonWidgetClass , thetop ,
00306                    XmNlabelString , xstr ,
00307                    XmNmarginHeight , 4 ,
00308                    XmNmarginWidth  , 4 ,
00309                    XmNtraversalOn , False ,
00310                    XmNinitialResourcesPersistent , False ,
00311                    XmNleftAttachment , XmATTACH_FORM ,
00312                    XmNtopAttachment  , XmATTACH_FORM ,
00313                    XmNtopOffset      , 7 ,
00314                    XmNleftOffset     , 5 ,
00315                NULL ) ;
00316    XmStringFree(xstr) ;
00317 
00318    XtAddCallback( dset_pb , XmNactivateCallback , TAG_dset_CB , NULL ) ;
00319 
00320    MCW_register_help( dset_pb , "Select dataset for tagging" ) ;
00321    MCW_register_hint( dset_pb , "Select dataset" ) ;
00322 
00323    /*** label at top to let user know who we are ***/
00324 
00325    xstr = XmStringCreateLtoR( DEFAULT_INFOLAB , XmFONTLIST_DEFAULT_TAG ) ;
00326    info_lab = XtVaCreateManagedWidget(
00327                  "AFNI" , xmLabelWidgetClass , thetop ,
00328                     XmNleftAttachment , XmATTACH_WIDGET ,
00329                     XmNleftWidget     , dset_pb ,
00330                     XmNleftOffset     , 10 ,
00331                     XmNtopAttachment  , XmATTACH_FORM ,
00332                     XmNtopOffset      , 5 ,
00333                     XmNrightAttachment, XmATTACH_FORM ,
00334                     XmNlabelString , xstr ,
00335                     XmNmarginHeight , 1 ,
00336                     XmNalignment , XmALIGNMENT_BEGINNING ,
00337                     XmNrecomputeSize , True ,
00338                     XmNinitialResourcesPersistent , False ,
00339                  NULL ) ;
00340    XmStringFree(xstr) ;
00341    MCW_register_help( info_lab , "Shows dataset being tagged" ) ;
00342    MCW_register_hint( info_lab , "Shows dataset being tagged" ) ;
00343 
00344    /*** separator for visual neatness ***/
00345 
00346    wjunk =  XtVaCreateManagedWidget(
00347              "AFNI" , xmSeparatorWidgetClass , thetop ,
00348                 XmNseparatorType , XmSINGLE_LINE ,
00349                 XmNleftAttachment , XmATTACH_FORM ,
00350                 XmNrightAttachment, XmATTACH_FORM ,
00351                 XmNtopAttachment  , XmATTACH_WIDGET ,
00352                 XmNtopWidget      , dset_pb ,
00353                 XmNtopOffset      , 5 ,
00354                 XmNinitialResourcesPersistent , False ,
00355              NULL ) ;
00356 
00357    /*** 1st set of action buttons below the line ***/
00358 
00359    actar = MCW_action_area( thetop , TAG_actor1 , NACT1 ) ;
00360 
00361    XtVaSetValues( actar ,
00362                      XmNleftAttachment , XmATTACH_FORM ,
00363                      XmNrightAttachment, XmATTACH_FORM ,
00364                      XmNtopAttachment  , XmATTACH_WIDGET ,
00365                      XmNtopOffset      , 5 ,
00366                      XmNtopWidget      , wjunk ,
00367                   NULL ) ;
00368 
00369    quit_pb  = (Widget) TAG_actor1[0].data ;  /* save individual buttons */
00370    help_pb  = (Widget) TAG_actor1[1].data ;
00371    read_pb  = (Widget) TAG_actor1[2].data ;
00372    write_pb = (Widget) TAG_actor1[3].data ;
00373    copy_pb  = (Widget) TAG_actor1[4].data ;
00374    save_pb  = (Widget) TAG_actor1[5].data ;
00375    done_pb  = (Widget) TAG_actor1[6].data ;
00376 
00377    /*** separator for visual neatness ***/
00378 
00379    wjunk =  XtVaCreateManagedWidget(
00380              "AFNI" , xmSeparatorWidgetClass , thetop ,
00381                 XmNseparatorType  , XmSINGLE_LINE ,
00382                 XmNleftAttachment , XmATTACH_FORM ,
00383                 XmNrightAttachment, XmATTACH_FORM ,
00384                 XmNtopAttachment  , XmATTACH_WIDGET ,
00385                 XmNtopWidget      , actar ,
00386                 XmNtopOffset      , 5 ,
00387                 XmNinitialResourcesPersistent , False ,
00388              NULL ) ;
00389 
00390    /*** 2nd set of action buttons ***/
00391 
00392    actar = MCW_action_area( thetop , TAG_actor2 , NACT2 ) ;
00393 
00394    XtVaSetValues( actar ,
00395                      XmNleftAttachment , XmATTACH_FORM ,
00396                      XmNrightAttachment, XmATTACH_FORM ,
00397                      XmNtopAttachment  , XmATTACH_WIDGET ,
00398                      XmNtopOffset      , 5 ,
00399                      XmNtopWidget      , wjunk ,
00400                   NULL ) ;
00401 
00402    set_pb     = (Widget) TAG_actor2[0].data ;  /* save individual buttons */
00403    clear_pb   = (Widget) TAG_actor2[1].data ;
00404    clearall_pb= (Widget) TAG_actor2[2].data ;
00405    add_pb     = (Widget) TAG_actor2[3].data ;
00406    delete_pb  = (Widget) TAG_actor2[4].data ;
00407    relabel_pb = (Widget) TAG_actor2[5].data ;
00408    beep_pb    = (Widget) TAG_actor2[6].data ;
00409 
00410    /*** separator for visual neatness ***/
00411 
00412    wjunk =  XtVaCreateManagedWidget(
00413              "AFNI" , xmSeparatorWidgetClass , thetop ,
00414                 XmNseparatorType  , XmSINGLE_LINE ,
00415                 XmNleftAttachment , XmATTACH_FORM ,
00416                 XmNrightAttachment, XmATTACH_FORM ,
00417                 XmNtopAttachment  , XmATTACH_WIDGET ,
00418                 XmNtopWidget      , actar ,
00419                 XmNtopOffset      , 5 ,
00420                 XmNinitialResourcesPersistent , False ,
00421              NULL ) ;
00422 
00423    /*** string chooser for tagset filename ***/
00424 
00425    file_strav = new_PLUGIN_strval( thetop , "Tag File:  " ) ;
00426    alter_PLUGIN_strval_width( file_strav , 37 ) ;
00427 
00428    MCW_reghelp_children( file_strav->rowcol ,
00429                          "Use this to enter the tagset filename\n"
00430                          "before using the Read or Write buttons.\n"
00431                          "(Tagset filenames must end in '.tag'.)"
00432                        ) ;
00433    MCW_reghint_children( file_strav->rowcol , "Used with Read/Write buttons" ) ;
00434 
00435    XtVaSetValues( file_strav->rowcol ,
00436                      XmNleftAttachment , XmATTACH_FORM ,
00437                      XmNrightAttachment, XmATTACH_FORM ,
00438                      XmNtopAttachment  , XmATTACH_WIDGET ,
00439                      XmNtopOffset      , 5 ,
00440                      XmNtopWidget      , wjunk ,
00441                   NULL ) ;
00442 
00443    /*** string chooser for relabeling tags ***/
00444 
00445    label_strav = new_PLUGIN_strval( thetop , "Tag Label: " ) ;
00446    alter_PLUGIN_strval_width( label_strav , 37 ) ;
00447 
00448    MCW_reghelp_children( label_strav->rowcol ,
00449                          "Use this to enter the new tag label\n"
00450                          "before using the Relabel button."
00451                        ) ;
00452    MCW_reghint_children( label_strav->rowcol , "Used with Relabel button" ) ;
00453 
00454    XtVaSetValues( label_strav->rowcol ,
00455                      XmNleftAttachment , XmATTACH_FORM ,
00456                      XmNrightAttachment, XmATTACH_FORM ,
00457                      XmNtopAttachment  , XmATTACH_WIDGET ,
00458                      XmNtopOffset      , 5 ,
00459                      XmNtopWidget      , file_strav->rowcol ,
00460                   NULL ) ;
00461 
00462    /*** arrowval to choose value that is drawn into dataset voxels ***/
00463 
00464    value_av = new_MCW_arrowval( thetop , "Tag Value: " ,
00465                                 MCW_AV_downup , -32767,32767,value_int ,
00466                                 MCW_AV_editext , 0 ,
00467                                 TAG_value_CB , NULL , NULL,NULL ) ;
00468 
00469    MCW_reghelp_children( value_av->wrowcol ,
00470                          "Use this to set the value that\n"
00471                          "will be associated with a tag."
00472                        ) ;
00473    MCW_reghint_children( value_av->wrowcol , "Value associated with tag" ) ;
00474 
00475    XtVaSetValues( value_av->wrowcol ,
00476                      XmNleftAttachment , XmATTACH_FORM ,
00477                      XmNrightAttachment, XmATTACH_FORM ,
00478                      XmNtopAttachment  , XmATTACH_WIDGET ,
00479                      XmNtopOffset      , 5 ,
00480                      XmNtopWidget      , label_strav->rowcol ,
00481                   NULL ) ;
00482 
00483    /*** separator for visual neatness ***/
00484 
00485    wjunk = XtVaCreateManagedWidget(
00486              "AFNI" , xmSeparatorWidgetClass , thetop ,
00487                 XmNseparatorType , XmSINGLE_LINE ,
00488                 XmNleftAttachment , XmATTACH_FORM ,
00489                 XmNrightAttachment, XmATTACH_FORM ,
00490                 XmNtopAttachment  , XmATTACH_WIDGET ,
00491                 XmNtopWidget      , value_av->wrowcol ,
00492                 XmNtopOffset      , 5 ,
00493                 XmNinitialResourcesPersistent , False ,
00494              NULL ) ;
00495 
00496    /*** scrolled window to hold the tag selectors ***/
00497 
00498    scrollw =
00499          XtVaCreateWidget(
00500            "AFNI" , xmScrolledWindowWidgetClass ,  thetop ,
00501               XmNscrollingPolicy , XmAUTOMATIC ,
00502               XmNleftAttachment  , XmATTACH_FORM ,
00503               XmNrightAttachment , XmATTACH_FORM ,
00504               XmNtopAttachment   , XmATTACH_WIDGET ,
00505               XmNbottomAttachment, XmATTACH_FORM ,
00506               XmNtopWidget       , wjunk ,
00507               XmNtopOffset       , 5 ,
00508               XmNtraversalOn , False ,
00509               XmNinitialResourcesPersistent , False ,
00510            NULL ) ;
00511 
00512    wframe =
00513          XtVaCreateWidget(
00514            "AFNI" , xmFrameWidgetClass , scrollw ,
00515                XmNshadowType , XmSHADOW_ETCHED_IN ,
00516                XmNshadowThickness , 5 ,
00517                XmNtraversalOn , False ,
00518                XmNinitialResourcesPersistent , False ,
00519             NULL ) ;
00520 
00521    workwin =
00522          XtVaCreateWidget(
00523            "AFNI" , xmRowColumnWidgetClass , wframe ,
00524               XmNpacking     , XmPACK_COLUMN ,
00525               XmNnumColumns  , 1 ,
00526               XmNorientation , XmVERTICAL ,
00527               XmNtraversalOn , False ,
00528               XmNinitialResourcesPersistent , False ,
00529            NULL ) ;
00530 
00531    XtVaGetValues( workwin , XmNforeground , &fg_pix , NULL ) ;
00532 
00533    XtVaSetValues( workwin ,
00534                      XmNradioBehavior , True ,
00535                      XmNradioAlwaysOne , False ,
00536                      XmNspacing      , 1 ,
00537                      XmNmarginHeight , 0 ,
00538                      XmNmarginWidth  , 0 ,
00539                   NULL ) ;
00540 
00541    /*** array of toggles for each possible tag ***/
00542 
00543    tagtog = (Widget *) XtMalloc( sizeof(Widget) * MAX_TAG_NUM ) ;
00544    toginv = (int *)    XtMalloc( sizeof(int)    * MAX_TAG_NUM ) ;
00545 
00546    for( ii=0 ; ii < MAX_TAG_NUM ; ii++ ){
00547       sprintf(tlab,"Tag #%d",ii) ;
00548       xstr = XmStringCreateLtoR( tlab , XmFONTLIST_DEFAULT_TAG ) ;
00549 
00550       tagtog[ii] =
00551            XtVaCreateWidget(
00552               "dialog" , xmToggleButtonWidgetClass , workwin ,
00553                  XmNlabelString    , xstr ,
00554                  XmNvisibleWhenOff , True ,
00555                  XmNmarginHeight   , 0 ,
00556                  XmNmarginWidth    , 0 ,
00557 #if 0
00558                  XmNselectColor    , fg_pix ,
00559 #endif
00560                  XmNtraversalOn    , False ,
00561                  XmNinitialResourcesPersistent , False ,
00562               NULL ) ;
00563 
00564       XmStringFree(xstr) ;
00565       toginv[ii] = 0 ;
00566       XtAddCallback( tagtog[ii] , XmNdisarmCallback , TAG_tog_CB , NULL ) ;
00567 
00568       if( ii < tognum ) XtManageChild( tagtog[ii] ) ;
00569 
00570       mytagset->tag[ii].set = 0 ;
00571       mytagset->tag[ii].ti  = 0 ;
00572       mytagset->tag[ii].x   = 0.0 ;
00573       mytagset->tag[ii].y   = 0.0 ;
00574       mytagset->tag[ii].z   = 0.0 ;
00575       mytagset->tag[ii].val = 0.0 ;
00576       strcpy( mytagset->tag[ii].label , tlab ) ;
00577    }
00578    mytagset->num = tognum ;
00579    strcpy( mytagset->label , "Tar-Palantir" ) ;
00580 
00581    /*** that's almost all ***/
00582 
00583    XtManageChild( workwin ) ;
00584    XtManageChild( wframe  ) ;
00585    XtManageChild( scrollw ) ;
00586    XtManageChild( thetop  ) ;
00587 
00588    XtRealizeWidget( shell ) ;  /* will not be mapped */
00589 
00590    /** set up widths and heights **/
00591 
00592    { XmFontList xflist ;
00593 
00594      for( ii=0 ; ii < MAX_TAG_LABEL-1 ; ii++ ) tlab[ii] = 'X' ;
00595      tlab[MAX_TAG_LABEL-1] = '\0' ;
00596 
00597      xstr = XmStringCreateLtoR( tlab , XmFONTLIST_DEFAULT_TAG ) ;
00598 
00599      XtVaGetValues( thetop , XmNbuttonFontList , &xflist , NULL ) ;
00600      hh = XmStringHeight( xflist , xstr ) ;
00601      ww = XmStringWidth ( xflist , xstr ) ;
00602      XmStringFree(xstr) ;
00603    }
00604 
00605    XtVaSetValues( shell ,
00606                      XmNminWidth  , ww+19*hh ,  /* semi-empirical numbers; */
00607                      XmNwidth     , ww+23*hh ,  /* all primes (for luck)  */
00608                      XmNminHeight , 23*hh ,
00609                      XmNheight    , 29*hh ,
00610                   NULL ) ;
00611 
00612    TAG_columnize() ;
00613    return ;
00614 }
00615 
00616 /*--------------------------------------------------------------------------*/
00617 
00618 static void TAG_redraw(void)
00619 {
00620    if( dset == NULL ) return ;
00621 
00622    if( dset->tagset == NULL ) dset->tagset = myXtNew(THD_usertaglist) ;
00623 
00624    *(dset->tagset) = *mytagset ;  /* copy all data in one swell foop */
00625 
00626    PLUTO_dset_redisplay_mode( dset , REDISPLAY_OVERLAY ) ;
00627    return ;
00628 }
00629 
00630 /*--------------------------------------------------------------------------*/
00631 
00632 static void TAG_quit_CB( Widget w, XtPointer client_data, XtPointer call_data )
00633 {
00634    if( editor_open ){
00635       if( dset != NULL && dset->tagset != NULL ){
00636          *(dset->tagset) = *oldtagset ;
00637          if( dset->tagset->num == 0 ) myXtFree(dset->tagset) ;
00638          PLUTO_dset_redisplay_mode( dset , REDISPLAY_OVERLAY ) ;
00639       }
00640       XtUnmapWidget( shell ) ; editor_open = 0 ; dset = NULL ;
00641       oldtagset->num = 0 ;
00642    }
00643    return ;
00644 }
00645 
00646 /*--------------------------------------------------------------------------*/
00647 
00648 static void TAG_value_CB( MCW_arrowval * av , XtPointer cd )
00649 {
00650    value_int   = av->ival ;
00651    value_float = av->fval ;
00652 
00653    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
00654    return ;
00655 }
00656 
00657 /*--------------------------------------------------------------------------*/
00658 
00659 static void TAG_columnize(void)
00660 {
00661    int nc = (tognum < 21) ? 1 : 2 ;
00662    XtVaSetValues( workwin , XmNnumColumns , nc , NULL ) ;
00663    return ;
00664 }
00665 
00666 /*--------------------------------------------------------------------------*/
00667 
00668 #define UNSET(j)                                                              \
00669   do{ XmToggleButtonSetState( tagtog[(j)] , 0 , False ) ;                     \
00670       mytagset->tag[(j)].set = 0 ;                                            \
00671       if( active_tog == (j) ) active_tog = -1 ;                               \
00672       if( toginv[(j)] ){ toginv[(j)] = 0; MCW_invert_widget( tagtog[(j)] ); } \
00673   } while(0)
00674 
00675 /*--------------------------------------------------------------------------*/
00676 
00677 static void TAG_add_CB( Widget w, XtPointer client_data, XtPointer call_data )
00678 {
00679    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
00680 
00681    if( tognum >= MAX_TAG_NUM ){
00682       char buf[64] ;
00683       sprintf(buf,"Maximum number of\nallowed tags is %d",MAX_TAG_NUM) ;
00684       POPUP_MESG(buf) ; BEEPIT ;
00685       return ;
00686    }
00687 
00688    UNSET(tognum) ;
00689    XtManageChild( tagtog[tognum] ) ;
00690    tognum++ ; mytagset->num = tognum ; TAG_columnize() ; DSET_OFF ;
00691    return ;
00692 }
00693 
00694 /*--------------------------------------------------------------------------*/
00695 
00696 static void TAG_delete_CB( Widget w, XtPointer client_data, XtPointer call_data )
00697 {
00698    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
00699 
00700    if( tognum <= 1 ){
00701       POPUP_MESG("You can't delete the\nonly remaining tag!") ;
00702       BEEPIT ; return ;
00703    }
00704 
00705    UNSET(tognum-1) ;
00706    XtUnmanageChild( tagtog[tognum-1] ) ;
00707    tognum-- ; mytagset->num = tognum ; TAG_columnize() ;
00708    TAG_redraw() ; DSET_OFF ;
00709    return ;
00710 }
00711 
00712 /*--------------------------------------------------------------------------*/
00713 
00714 static void TAG_set_CB( Widget w, XtPointer client_data, XtPointer call_data )
00715 {
00716    int ii = active_tog ;
00717 
00718    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
00719 
00720    if( ii < 0 || ii >= tognum ){
00721       BEEPIT ;
00722       POPUP_MESG( "Can't set a tag\nuntil one is selected" ) ;
00723       return ;
00724    }
00725 
00726    mytagset->tag[ii].set = 1 ;
00727    mytagset->tag[ii].ti  = im3d->vinfo->time_index ;
00728    mytagset->tag[ii].x   = im3d->vinfo->xi ;
00729    mytagset->tag[ii].y   = im3d->vinfo->yj ;
00730    mytagset->tag[ii].z   = im3d->vinfo->zk ;
00731    mytagset->tag[ii].val = value_float ;
00732 
00733    if( !toginv[ii] ){ toginv[ii] = 1 ; MCW_invert_widget( tagtog[ii] ) ; }
00734 
00735    DSET_OFF ; TAG_redraw() ;
00736    return ;
00737 }
00738 
00739 /*--------------------------------------------------------------------------*/
00740 
00741 static void TAG_clear_CB( Widget w, XtPointer client_data, XtPointer call_data )
00742 {
00743    int ii=active_tog , oldset ;
00744 
00745    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
00746 
00747    if( ii < 0 || ii >= tognum ){
00748       BEEPIT ;
00749       POPUP_MESG( "Can't clear a tag\nuntil one is selected" ) ;
00750       return ;
00751    }
00752 
00753    oldset = mytagset->tag[ii].set ;
00754    mytagset->tag[ii].set = 0 ;
00755 
00756    if( toginv[ii] ){ toginv[ii] = 0 ; MCW_invert_widget( tagtog[ii] ) ; }
00757 
00758    if( oldset ){ TAG_redraw() ; DSET_OFF ; }
00759    return ;
00760 }
00761 
00762 /*--------------------------------------------------------------------------*/
00763 
00764 static void TAG_clearall_CB( Widget w, XtPointer client_data, XtPointer call_data )
00765 {
00766    int ii , oldset=0 ;
00767 
00768    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
00769 
00770    if( tognum < 1 ){ BEEPIT ; return ; }  /* should not occur */
00771 
00772    for( ii=0 ; ii < tognum ; ii++ ){
00773       if( mytagset->tag[ii].set ) oldset++ ;
00774       mytagset->tag[ii].set = 0 ;
00775       if( toginv[ii] ){ toginv[ii] = 0 ; MCW_invert_widget( tagtog[ii] ) ; }
00776    }
00777 
00778    if( oldset ){ TAG_redraw() ; DSET_OFF ; }
00779    return ;
00780 }
00781 
00782 /*--------------------------------------------------------------------------*/
00783 
00784 static void TAG_relabel_CB( Widget w, XtPointer client_data, XtPointer call_data )
00785 {
00786    char * str=get_PLUGIN_strval(label_strav) ;
00787    int ii=active_tog , ll,kk,nn ;
00788    XmString xstr ;
00789 
00790    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
00791 
00792    if( str == NULL ){ BEEPIT ; return ; }  /* should not occur */
00793 
00794    if( str[0] == '\0' || ii < 0 || ii >= tognum ){
00795       BEEPIT; XtFree(str);
00796       POPUP_MESG( "Can't relabel a tag unless\n"
00797                   "one is selected AND a new\n"
00798                   "label is typed in" ) ;
00799       return;
00800    }
00801 
00802    ll = strlen(str) ;
00803    if( ll >= MAX_TAG_LABEL ){ str[MAX_TAG_LABEL-1] = '\0'; ll = strlen(str); }
00804    for( kk=nn=0 ; kk < ll ; kk++ ) if( isspace(str[kk]) ) nn++ ;
00805    if( nn == ll ){
00806       BEEPIT; XtFree(str);
00807       POPUP_MESG( "Can't relabel a\ntag to all blanks!" ) ;
00808       return ;
00809    }
00810 
00811    xstr = XmStringCreateLtoR( str , XmFONTLIST_DEFAULT_TAG ) ;
00812    XtVaSetValues( tagtog[ii] , XmNlabelString , xstr , NULL ) ;
00813    XmStringFree(xstr) ;
00814 
00815    strcpy( mytagset->tag[ii].label , str ) ;
00816    XtFree(str) ; DSET_OFF ;
00817    return ;
00818 }
00819 
00820 /*--------------------------------------------------------------------------*/
00821 
00822 static void TAG_tog_CB( Widget w, XtPointer client_data, XtPointer call_data )
00823 {
00824    int ii ;
00825 
00826    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
00827 
00828    for( ii=0 ; ii < tognum ; ii++ ){
00829       if( XmToggleButtonGetState( tagtog[ii] ) ){  /* found it */
00830          active_tog = ii ;
00831          if( mytagset->tag[ii].set ){              /* if already set */
00832             AFNI_jumpto_dicom( im3d , mytagset->tag[ii].x ,
00833                                       mytagset->tag[ii].y , mytagset->tag[ii].z ) ;
00834 
00835             AV_assign_fval( value_av , mytagset->tag[ii].val ) ;
00836             value_int   = value_av->ival ;
00837             value_float = value_av->fval ;
00838          }
00839          return ;
00840       }
00841    }
00842 
00843    active_tog = -1 ; return ;  /* found nothing */
00844 }
00845 
00846 /*--------------------------------------------------------------------------*/
00847 
00848 static void TAG_write_CB( Widget w, XtPointer client_data, XtPointer call_data )
00849 {
00850    char * str=get_PLUGIN_strval(file_strav) , * cpt ;
00851    int ii , jj , ltop ;
00852    FILE * fp ;
00853 
00854    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
00855 
00856    if( str == NULL ){ BEEPIT ; return ; }  /* should not occur */
00857 
00858    if( str[0] == '\0' || tognum < 1 ){
00859       XtFree(str) ; BEEPIT ;
00860       POPUP_MESG( "Can't write tags to a file\n"
00861                   "until a filename is typed in" ) ;
00862       return ;
00863    }
00864 
00865    cpt = strstr( str , ".tag" ) ;
00866    if( cpt == NULL ){
00867       ii = strlen(str) ;
00868       cpt = XtMalloc(ii+8) ;
00869       strcpy(cpt,str) ;
00870       if( cpt[ii-1] != '.' ) strcat( cpt , "." ) ;
00871       strcat( cpt , "tag" ) ;
00872       XtFree(str) ;
00873       str = cpt ;
00874    }
00875 
00876    if( !THD_filename_ok(str) ){
00877       XtFree(str) ; BEEPIT ;
00878       POPUP_MESG( "The filename you entered\nhas illegal characters!" ) ;
00879       return ;
00880    }
00881 
00882    fp = fopen( str , "w" ) ;
00883    if( fp == NULL ){
00884       XtFree(str) ; BEEPIT ;
00885       POPUP_MESG( "Can't open output file!\n" ) ;
00886       return ;
00887    }
00888 
00889    ltop = 6 ;
00890    for( ii=0 ; ii < tognum ; ii++ ){
00891       jj   = strlen( mytagset->tag[ii].label ) ;
00892       ltop = MAX( jj , ltop ) ;
00893    }
00894 
00895    cpt = XtMalloc( MAX_TAG_LABEL+256 ) ;
00896 
00897    strcpy(cpt,"# Label") ;
00898    for( jj=strlen(cpt) ; jj < ltop+2 ; jj++ )
00899       strcat( cpt , "_" ) ;
00900    strcat(cpt,"  ") ;
00901    strcat(cpt," _____x_____ _____y_____ _____z_____ ____val____ _t_") ;
00902    fprintf(fp,"%s\n",cpt) ;
00903 
00904    for( ii=0 ; ii < tognum ; ii++ ){
00905       strcpy( cpt , "'" ) ;
00906       strcat( cpt , mytagset->tag[ii].label ) ;
00907       strcat( cpt , "'" ) ;
00908 
00909       if( mytagset->tag[ii].set ){
00910          for( jj=strlen(cpt) ; jj < ltop+4 ; jj++ )
00911             strcat( cpt , " " ) ;
00912 
00913          fprintf(fp , "%s %11.4g %11.4g %11.4g %11.4g %3d\n" ,
00914                  cpt, mytagset->tag[ii].x, mytagset->tag[ii].y, mytagset->tag[ii].z,
00915                       mytagset->tag[ii].val, mytagset->tag[ii].ti ) ;
00916       } else {
00917          fprintf(fp , "%s\n" , cpt ) ;
00918       }
00919    }
00920 
00921    fclose(fp) ; XtFree(cpt) ;
00922    fprintf(stderr,"Wrote tag file %s\n",str) ;
00923    XtFree(str) ; return ;
00924 }
00925 
00926 /*--------------------------------------------------------------------------*/
00927 
00928 static void TAG_reset_widgets(void)
00929 {
00930    int ii ;
00931    XmString xstr ;
00932 
00933    XtUnmanageChild(wframe) ;
00934 
00935    for( ii=0 ; ii < tognum ; ii++ ){
00936 
00937       XtManageChild( tagtog[ii] ) ;
00938       XmToggleButtonSetState( tagtog[ii] , 0 , False ) ;
00939 
00940       if( mytagset->tag[ii].set && !toginv[ii] ){
00941          toginv[ii] = 1; MCW_invert_widget( tagtog[ii] );
00942       } else if( !mytagset->tag[ii].set && toginv[ii] ){
00943          toginv[ii] = 0; MCW_invert_widget( tagtog[ii] );
00944       }
00945 
00946       xstr = XmStringCreateLtoR( mytagset->tag[ii].label , XmFONTLIST_DEFAULT_TAG ) ;
00947       XtVaSetValues( tagtog[ii] , XmNlabelString , xstr , NULL ) ;
00948       XmStringFree(xstr) ;
00949    }
00950 
00951    for( ; ii < MAX_TAG_NUM ; ii++ ){
00952       UNSET(ii) ;
00953       XtUnmanageChild( tagtog[ii] ) ;
00954    }
00955 
00956    TAG_columnize() ; XtManageChild(wframe) ;
00957    active_tog = -1 ; return ;
00958 }
00959 
00960 /*--------------------------------------------------------------------------*/
00961 
00962 static void TAG_read_CB( Widget w, XtPointer client_data, XtPointer call_data )
00963 {
00964    char * str=get_PLUGIN_strval(file_strav) , * cpt , buf[256] , quote ;
00965    int ii , jj , ntog , lbuf , kk ;
00966    FILE * fp ;
00967    char  new_label[MAX_TAG_LABEL] ;
00968    float new_x , new_y , new_z , new_val ;
00969    int   new_ti , new_set ;
00970    XmString xstr ;
00971 
00972    /*-- sanity checks --*/
00973 
00974    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
00975 
00976    if( str == NULL ){ BEEPIT ; return ; }  /* should not happen */
00977 
00978    if( str[0] == '\0' ){
00979       XtFree(str) ; BEEPIT ;
00980       POPUP_MESG( "Can't read a tagset until\nyou type in a filename" ) ;
00981       return ;
00982    }
00983 
00984    /*-- check for suffix on filename --*/
00985 
00986    cpt = strstr( str , ".tag" ) ;
00987    if( cpt == NULL ){
00988       ii = strlen(str) ;
00989       cpt = XtMalloc(ii+8) ;
00990       strcpy(cpt,str) ;
00991       if( cpt[ii-1] != '.' ) strcat( cpt , "." ) ;
00992       strcat( cpt , "tag" ) ;
00993       XtFree(str) ;
00994       str = cpt ;
00995    }
00996 
00997    /*-- open file --*/
00998 
00999    fp = fopen( str , "r" ) ;
01000    if( fp == NULL ){
01001       XtFree(str) ; BEEPIT ;
01002       POPUP_MESG( "Can't open input file!" ) ;
01003       return ;
01004    }
01005 
01006    /*-- scan each line for a tag definition --*/
01007 
01008    ntog = 0 ;
01009    while( ntog < MAX_TAG_NUM ){
01010       cpt = fgets( buf , 256 , fp ) ;   /* read line from disk */
01011       if( cpt == NULL ) break ;         /* nothing => exit */
01012       if( buf[0] == '#'  ) continue ;   /* comment => skip this line */
01013       if( buf[0] == '\n' ) continue ;
01014       if( buf[0] == '\0' ) continue ;
01015 
01016       lbuf = strlen(buf) ;              /* skip whitespace at start */
01017       jj = 0 ;
01018       while( jj < lbuf && isspace(buf[jj]) ) jj++ ;
01019       if( jj == lbuf ) continue ;       /* was a blank line => skip */
01020       if( buf[jj] == '#'  ) continue ;  /* comment */
01021 
01022       /* scan for new label */
01023 
01024       if( buf[jj] == '\'' || buf[jj] == '\"' ){  /* scan to matching quote */
01025          quote = buf[jj] ; jj++ ; kk = jj ;
01026          while( kk < lbuf && buf[kk] != quote ) kk++ ;
01027          if( kk == lbuf ) kk-- ;
01028       } else {                                   /* scan to nonblank */
01029          kk = jj+1 ;
01030          while( kk < lbuf && !isspace(buf[kk]) ) kk++ ;
01031       }
01032       for( ii=0 ; ii < MAX_TAG_LABEL-1 && jj < kk ; ii++,jj++ )
01033          new_label[ii] = buf[jj] ;
01034       new_label[ii] = '\0' ;
01035       if( strlen(new_label) == 0 ) continue ;  /* error => skip */
01036       jj = kk+1 ;
01037 
01038       /* scan for x y z val ti */
01039 
01040       new_set = new_ti = 0 ;
01041       new_x   = new_y  = new_z = new_val = 0.0 ;
01042       if( jj < lbuf-4 ){
01043          kk = sscanf( buf+jj , "%f %f %f %f %d" ,
01044                       &new_x , &new_y , &new_z , &new_val , &new_ti ) ;
01045          if( kk >= 3 ) new_set = 1 ;  /* got x y z, at least */
01046       }
01047 
01048       /* set values */
01049 
01050       strcpy( mytagset->tag[ntog].label , new_label ) ;
01051       mytagset->tag[ntog].set = new_set ;
01052       mytagset->tag[ntog].ti  = new_ti  ;
01053       mytagset->tag[ntog].x   = new_x   ;
01054       mytagset->tag[ntog].y   = new_y   ;
01055       mytagset->tag[ntog].z   = new_z   ;
01056       mytagset->tag[ntog].val = new_val ;
01057       ntog++ ;
01058    }
01059 
01060    fclose(fp) ;  /* done with file */
01061 
01062    if( ntog == 0 ){                                 /* no tags ==> error */
01063       sprintf(buf,"Couldn't read tagset from\n"
01064                   "file %s" , str ) ;
01065       POPUP_MESG( buf ) ;
01066       BEEPIT ; XtFree(str) ; return ;
01067    }
01068 
01069    /*-- now reset the widgets --*/
01070 
01071    tognum = mytagset->num = ntog ;
01072    TAG_reset_widgets() ;
01073    TAG_redraw() ; DSET_OFF ; XtFree(str) ;
01074    return ;
01075 }
01076 
01077 /*--------------------------------------------------------------------------*/
01078 
01079 static void TAG_get_dset_CB( int num, THD_3dim_dataset ** dslist, void * cd )
01080 {
01081    char str[256] , * tnam ;
01082    XmString xstr ;
01083 
01084    /*-- sanity checks --*/
01085 
01086    if( !IM3D_OPEN(im3d) || !editor_open ){
01087       BEEPIT ; POPDOWN_strlist_chooser ;
01088       TAG_quit_CB(NULL,NULL,NULL) ; return ;
01089    }
01090 
01091    /* this should not occur: */
01092 
01093    if( num != 1 || dslist == NULL || !ISVALID_DSET(dslist[0]) ){ BEEPIT; return; }
01094 
01095    /* assign global variable */
01096 
01097    dset = dslist[0] ;
01098 
01099    /*-- change the informational label --*/
01100 
01101    sprintf(str,"%s%s", DSET_DIRNAME(dset) , DSET_FILECODE(dset) ) ;
01102    tnam = THD_trailname( str , SESSTRAIL+1 ) ;
01103    xstr = XmStringCreateLtoR( tnam , XmFONTLIST_DEFAULT_TAG ) ;
01104    XtVaSetValues( info_lab , XmNlabelString , xstr , NULL ) ;
01105    XmStringFree(xstr) ;
01106 
01107    /*-- if the new dataset has tags, use them --*/
01108 
01109    if( dset->tagset != NULL && dset->tagset->num > 0 ){
01110       *mytagset  = *(dset->tagset) ;  /* copy all data in one swell foop */
01111       *oldtagset = *mytagset ;        /* backup copy */
01112       tognum = mytagset->num ;
01113       TAG_reset_widgets() ;
01114    } else {
01115       oldtagset->num = 0 ;
01116       if( dset->tagset == NULL ){
01117          dset->tagset = myXtNew(THD_usertaglist) ;
01118          dset->tagset->num = 0 ;
01119       }
01120       if( tognum > 0 ) TAG_clearall_CB(NULL,NULL,NULL) ;
01121    }
01122 
01123    TAG_onoff( 1 ) ;
01124    return ;
01125 }
01126 
01127 /*--------------------------------------------------------------------------*/
01128 
01129 static int TAG_check_dataset( THD_3dim_dataset * qset, void * cd )
01130 {
01131 #if 0
01132    return ISANAT(qset) ;
01133 #else
01134    return 1 ;  /* All of them, Frank */
01135 #endif
01136 }
01137 
01138 static int TAG_check_copyset( THD_3dim_dataset * qset, void * cd )
01139 {
01140    return ( ISANAT(qset)         && !EQUIV_DSETS(qset,dset) &&
01141             qset->tagset != NULL && qset->tagset->num > 0      ) ;
01142 }
01143 
01144 /*--------------------------------------------------------------------------*/
01145 
01146 static void TAG_dset_CB( Widget w, XtPointer client_data, XtPointer call_data )
01147 {
01148    /*-- sanity checks --*/
01149 
01150    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
01151 
01152    /*-- just show a chooser, let the user commune with the list --*/
01153 
01154    PLUTO_popup_dset_chooser( help_pb , im3d->vinfo->view_type , 0 ,
01155                              TAG_check_dataset , TAG_get_dset_CB , NULL ) ;
01156 
01157    return ;
01158 }
01159 
01160 /*--------------------------------------------------------------------------*/
01161 
01162 static void TAG_save_CB( Widget w, XtPointer client_data, XtPointer call_data )
01163 {
01164    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
01165 
01166    if( dset == NULL ) return ;  /* nothing to do */
01167 
01168    if( dset->tagset == NULL ){
01169       dset->tagset = myXtNew(THD_usertaglist) ;
01170       ADDTO_KILL( dset->kl , dset->tagset ) ;
01171    }
01172 
01173    *(dset->tagset) = *mytagset ;  /* copy all data in one swell foop */
01174    *oldtagset      = *mytagset ;  /* backup copy is replaced */
01175 
01176    DSET_write_header(dset) ;
01177    TAG_redraw() ; DSET_ON ;
01178    return ;
01179 }
01180 
01181 /*--------------------------------------------------------------------------*/
01182 
01183 static void TAG_onoff( int on )
01184 {
01185    Boolean sen ;
01186    int ii ;
01187 
01188    sen = (Boolean) on ;
01189    for( ii=0 ; onoff_wid[ii] != NULL ; ii++ )
01190       SENSITIZE( *(onoff_wid[ii]) , sen ) ;    /* see xutil.h */
01191 
01192    on_flag = on ;
01193    return ;
01194 }
01195 
01196 /*--------------------------------------------------------------------------*/
01197 
01198 static void TAG_done_CB( Widget w, XtPointer client_data, XtPointer call_data )
01199 {
01200    TAG_save_CB(NULL,NULL,NULL) ; dset = NULL ;
01201    TAG_quit_CB(NULL,NULL,NULL) ;
01202    return ;
01203 }
01204 
01205 /*--------------------------------------------------------------------------*/
01206 
01207 static void TAG_get_copy_CB( int num, THD_3dim_dataset ** dslist, void * cd )
01208 {
01209    char str[256] , * tnam ;
01210    THD_3dim_dataset * qset ;
01211    XmString xstr ;
01212 
01213    /*-- sanity checks --*/
01214 
01215    if( !IM3D_OPEN(im3d) || !editor_open ){
01216       BEEPIT ; POPDOWN_strlist_chooser ;
01217       TAG_quit_CB(NULL,NULL,NULL) ; return ;
01218    }
01219 
01220    if( num != 1 || dslist == NULL || !ISVALID_DSET(dslist[0]) ){ BEEPIT; return; }
01221 
01222    qset = dslist[0] ; if( qset->tagset == NULL ){ BEEPIT; return; }
01223 
01224    *mytagset = *(qset->tagset) ;
01225    tognum    = mytagset->num ;
01226 
01227    TAG_reset_widgets() ; TAG_redraw() ; DSET_OFF ;
01228    return ;
01229 }
01230 
01231 /*--------------------------------------------------------------------------*/
01232 
01233 static void TAG_copy_CB( Widget w, XtPointer client_data, XtPointer call_data )
01234 {
01235    /*-- sanity checks --*/
01236 
01237    if( !IM3D_OPEN(im3d) ){ BEEPIT ; TAG_quit_CB(NULL,NULL,NULL) ; return ; }
01238 
01239    /*-- just show a chooser, let the user commune with the list --*/
01240 
01241    PLUTO_popup_dset_chooser( help_pb , im3d->vinfo->view_type , 0 ,
01242                              TAG_check_copyset , TAG_get_copy_CB , NULL ) ;
01243 
01244    return ;
01245 }
01246 
01247 /*--------------------------------------------------------------------------*/
01248 
01249 static void TAG_help_CB( Widget w, XtPointer client_data, XtPointer call_data )
01250 {
01251    (void ) new_MCW_textwin( help_pb ,
01252 
01253      "This plugin can be used to attach a collection of 'tags' to an anatomical\n"
01254      "dataset.  Each tag has associated with it a label, a set of (x,y,z)\n"
01255      "coordinates, and a numerical value.  If a tag is 'set', then a marker will\n"
01256      "be displayed at its location when the dataset is being viewed, and when\n"
01257      "'See Markers' is enabled on the AFNI control panel.  Tags that are not set\n"
01258      "are not shown and are not used for any purpose.\n"
01259 
01260      "\n"
01261      "The first step in defining a set of tags for a dataset is to pick the\n"
01262      "dataset to be operated upon.  Normally, this would be the dataset that\n"
01263      "you are viewing in some window (otherwise you won't see the tags).\n"
01264      "Choosing a dataset for tag operations is done with the 'Dataset' button\n"
01265      "at the top of the plugin interface.  This will popup a chooser that\n"
01266      "lets you select any anatomical dataset.  After you select the dataset,\n"
01267      "its existing tags (if any) are loaded into the plugin and can then\n"
01268      "be modified.\n"
01269 
01270      "\n"
01271      "There are two rows of control buttons below the 'Dataset' choice button.\n"
01272      "The first row handles large operations on the whole set of tags.  The\n"
01273      "second row is for retail operations on the status of individual tags.\n"
01274      "Most of the control buttons are deactivated until you select a dataset.\n"
01275      "Below these rows is a set of data entry fields, and below that a list\n"
01276      "of all the tags currently defined (whether set or not -- tags that are\n"
01277      "set are shown in inverted colors).  Each entry in the tag list has a\n"
01278      "selection button.  At most one tag can be selected at a given time.\n"
01279      "\n"
01280 
01281      "Row 1 buttons are:\n"
01282      "-----------------\n"
01283      "'Quit': Exit the plugin without saving changes back to the dataset.\n"
01284      "\n"
01285      "'Help': Display this message.\n"
01286      "\n"
01287      "'Read': Read in a tagset description file, replacing the current tag\n"
01288      "        definitions.  Each line in a tagset file (extension '.tag')\n"
01289      "        defines one tag.  The first entry on a line is the tag label.\n"
01290      "        If the label contains any blanks, it should be enclosed in\n"
01291      "        quotes (either \"double\" or 'single' quotes will work).\n"
01292      "        Following the label, it is legal to put three numbers, which\n"
01293      "        will be interpreted as the (x,y,z) coordinates of the tag.\n"
01294      "        If these numbers are present, the tag will be set and displayed.\n"
01295      "\n"
01296      "'Write': Write the current set of tags to a '.tag' file, which can\n"
01297      "         later be read back in using the 'Read' button.\n"
01298      "   N.B.: Tag coordinates are stored in Dicom order\n"
01299      "              x = R-L coordinate (R < 0, L > 0)\n"
01300      "              y = A-P coordinate (A < 0, P > 0)\n"
01301      "              z = I-S coordinate (I < 0, S > 0)\n"
01302      "\n"
01303      "'Copy': Copy the set of tags from another dataset.\n"
01304      "\n"
01305      "'Save': Save the current set of tags into the dataset .HEAD file.\n"
01306      "        If this is not done before 'Quit', then changes made to the\n"
01307      "        tagset will not be saved.\n"
01308      "\n"
01309      "'Done': Combines the operations of 'Save' and then 'Quit'.\n"
01310      "\n"
01311 
01312      "Row 2 buttons are:\n"
01313      "-----------------\n"
01314      "'Set': Sets the selected tag to be at the current crosshair location.\n"
01315      "\n"
01316      "'Clear': Un-sets the current tag.\n"
01317      "\n"
01318      "'Clr All': Un-sets all tags.\n"
01319      "\n"
01320      "'Add': Adds 1 new tag to the end of the list.  There is a maximum of\n"
01321      "       100 tags allowed.\n"
01322      "\n"
01323      "'Delete': Deletes the last tag from the list.\n"
01324      "\n"
01325      "'Relabel': Changes the label of the selected tag.\n"
01326      "\n"
01327 
01328      "Data entry fields are:\n"
01329      "---------------------\n"
01330      "'Tag File': You enter the name of the tagset file for 'Read' and 'Write'\n"
01331      "            operations here.\n"
01332      "\n"
01333      "'Tag Label': You enter the new label for the selected tag here, for use\n"
01334      "             with the 'Relabel' operation.\n"
01335      "\n"
01336      "'Tag Value': You enter the numerical value to be attached to a tag here,\n"
01337      "             for use with the 'Set' operation.\n"
01338      "\n"
01339 
01340      "Nota Bene\n"
01341      "---------\n"
01342      "The tag value is not used for anything yet.  Any suggestions?\n"
01343      "\n"
01344      "By using the 'Add', 'Delete', and 'Relabel' buttons, it is possible to\n"
01345      "create your own collection of tag definitions.  However, it is generally\n"
01346      "easier to use an external editor (e.g., 'vi') to create a .tag file and\n"
01347      "then read it in with the 'Read' button.\n"
01348      "\n"
01349      "Once you make a change to a tagset, the 'Dataset' button will be disabled\n"
01350      "until 'Save' is used.  This is a safety measure to help prevent accidental\n"
01351      "loss of changes.  If you want to discard the changes, use 'Quit'.\n"
01352      "\n"
01353      "The color of a dataset tag is controlled by the 'Primary Markers' color,\n"
01354      "which is set on the 'Define Markers' control panel in the main AFNI control\n"
01355      "window.  The tags are displayed as a cross within a diamond.\n"
01356      "\n"
01357      "The program 3dTagalign will read the tag coordinates from one dataset and\n"
01358      "rotate/translate that dataset to match the tag coordinates from another\n"
01359      "dataset (in the least squares sense).  See '3dTagalign -help' for details.\n"
01360      "\n"
01361      "============================\n"
01362      "AUTHOR: RW Cox, October 1998\n"
01363      "============================\n"
01364 
01365     , TEXT_READONLY ) ;
01366    return ;
01367 }
01368 
01369 /*--------------------------------------------------------------------------*/
01370 
01371 #define NMSG 6
01372 
01373 static void TAG_beep_CB( Widget w, XtPointer client_data, XtPointer call_data )
01374 {
01375    static int nbeep = 0 ;
01376    static char * msg[] = { "What did you expect,\na choir of angels?"                ,
01377                            "Apparently some people\ncan't take a hint."              ,
01378                            "You aren't tired\nof this game YET?!"                    ,
01379                            "I'm getting tired of\nthis.  I'm warning you!"           ,
01380                            "This is the last time!\nOnce more, and you'll be sorry!" ,
01381                            "You can't say I didn't warn you.\nNyah Nyah Nyah."
01382                          } ;
01383 
01384    POPUP_MESG( msg[nbeep] ) ; nbeep++ ; BEEPIT ;
01385 
01386    if( nbeep >= NMSG ) SENSITIZE(beep_pb,False) ;
01387    return ;
01388 }
 

Powered by Plone

This site conforms to the following standards: