/* 
 * $Id: x11file.c,v 1.15 2003/02/16 12:43:37 isizaka Exp isizaka $
 * 
 * This file is part of "Ngraph for X11".
 * 
 * Copyright (C) 2002, Satoshi ISHIZAKA. isizaka@msa.biglobe.ne.jp
 * 
 * "Ngraph for X11" is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * "Ngraph for X11" is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 */

/**
 *
 * $Log: x11file.c,v $
 * Revision 1.15  2003/02/16 12:43:37  isizaka
 * for release 6.13.18
 *
 * Revision 1.14  2002/07/06 08:57:25  isizaka
 * change to GPL.
 *
 * Revision 1.13  2002/04/18 12:02:45  isizaka
 * Bug fix: FitDialogCopy (thanks to Mr. H. Ito, hito@crl.go.jp)
 *
 * Revision 1.12  2001/07/14 17:44:50  isizaka
 * for 6.03.14
 *
 * Revision 1.11  2001/03/23 12:17:43  isizaka
 * for 6.3.13
 *
 * Revision 1.10  2000/11/10 13:22:13  isizaka
 * Bug fix: FitDialogSetup (thanks to Mr. H. Ito, hito@crl.go.jp)
 *
 * Revision 1.9  2000/10/16 15:08:45  isizaka
 * add "Apply/Draw" button in fitting dialog.
 *
 * Revision 1.8  1999/10/16 08:31:18  isizaka
 * add 'Fit settings' popup.
 *
 * Revision 1.7  1999/05/31 10:33:13  isizaka
 * for release 6.03.03
 *
 * Revision 1.6  1999/05/08 13:31:30  isizaka
 * for release 6.03.02
 *
 * Revision 1.5  1999/04/15 12:14:26  isizaka
 * for release 6.03.01
 *
 * Revision 1.4  1999/04/11 06:09:20  isizaka
 * *** empty log message ***
 *
 * Revision 1.3  1999/03/21 12:51:43  isizaka
 * minor change
 *
 * Revision 1.2  1999/03/20 12:32:54  isizaka
 * minor change
 *
 * Revision 1.1  1999/03/17 13:29:01  isizaka
 * Initial revision
 *
 *
 **/

#include <Xm/XmAll.h>
#include <X11/keysym.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

#include "motif12.h"

#include "ngraph.h"
#include "object.h"
#include "ioutil.h"
#include "nstring.h"
#include "mathcode.h"
#include "mathfn.h"
#include "gra.h"
#include "spline.h"
#include "config.h"

#include "x11gui.h"
#include "x11dialg.h"
#include "x11menu.h"
#include "ox11menu.h"
#include "x11graph.h"
#include "x11view.h"
#include "x11file.h"
#include "x11commn.h"

#define FITSAVE "fit.ngp"

void MathTextDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc;
  struct MathTextDialog *d;
  char **array;
  int num;

  d=(struct MathTextDialog *)data;
  d->math=NULL;
  if (makewidget) {
    ac=0;
    XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
    XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
    ac=0;
    XtManageChild(XmCreateLabel(rc,"Math",al,ac));
    ac=0;
    XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
    XtManageChild(XmCreateComboBox(rc,"math",al,ac));
  }
  num=arraynum(menulocal.mathlist);
  array=(char **)arraydata(menulocal.mathlist);
  SetComboList2(w,"*math",array,num);
  XtVaSetValues(GetComboBoxText(d->widget,"*math"),XmNvalue,d->Text,NULL);
}

void MathTextDialogClose(Widget w,void *data)
{
  struct MathTextDialog *d;

  d=(struct MathTextDialog *)data;
  XtVaGetValues(GetComboBoxText(d->widget,"*math"),XmNvalue,&(d->math),NULL);
}

void MathTextDialog(struct MathTextDialog *data,char *text)
{
  data->SetupWindow=MathTextDialogSetup;
  data->CloseWindow=MathTextDialogClose;
  data->Text=text;
}

void MathDialogSetupItem(Widget w,struct MathDialog *d)
{
  int i,len;
  char *s,*math;
  char *field=NULL;
  XmString xs;

  XmListDeleteAllItems(XtNameToWidget(w,"*list"));
  if (d->Mode==0) field="math_x";
  else if (d->Mode==1) field="math_y";
  else if (d->Mode==2) field="func_f";
  else if (d->Mode==3) field="func_g";
  else if (d->Mode==4) field="func_h";
  for (i=0;i<=chkobjlastinst(d->Obj);i++) {
    math=NULL;
    getobj(d->Obj,field,i,0,NULL,&math);
    if (math==NULL) len=0;
    else len=strlen(math);
    if ((s=(char *)memalloc(len+10))!=NULL) {
      if (math==NULL) sprintf(s,"%d:",i);
      else sprintf(s,"%d: %s",i,math);
      xs=XmStringCreateLocalized(s);
      XmListAddItem(XtNameToWidget(w,"*list"),xs,0);
      XmStringFree(xs);
      memfree(s);
    } else {
      xs=XmStringCreateLocalized("");
      XmListAddItem(XtNameToWidget(w,"*list"),xs,0);
      XmStringFree(xs);
    }
  }
  XmToggleButtonSetState(XtNameToWidget(w,"*X"),FALSE,TRUE);
  XmToggleButtonSetState(XtNameToWidget(w,"*Y"),FALSE,TRUE);
  XmToggleButtonSetState(XtNameToWidget(w,"*F"),FALSE,TRUE);
  XmToggleButtonSetState(XtNameToWidget(w,"*G"),FALSE,TRUE);
  XmToggleButtonSetState(XtNameToWidget(w,"*H"),FALSE,TRUE);
  if (d->Mode==0) 
    XmToggleButtonSetState(XtNameToWidget(w,"*X"),TRUE,TRUE);
  else if (d->Mode==1) 
    XmToggleButtonSetState(XtNameToWidget(w,"*Y"),TRUE,TRUE);
  else if (d->Mode==2) 
    XmToggleButtonSetState(XtNameToWidget(w,"*F"),TRUE,TRUE);
  else if (d->Mode==3) 
    XmToggleButtonSetState(XtNameToWidget(w,"*G"),TRUE,TRUE);
  else if (d->Mode==4) 
    XmToggleButtonSetState(XtNameToWidget(w,"*H"),TRUE,TRUE);
}

void MathDialogMode(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct MathDialog *d;

  d=(struct MathDialog *)client_data;
  if (w==XtNameToWidget(d->widget,"*X")) d->Mode=0;
  else if (w==XtNameToWidget(d->widget,"*Y")) d->Mode=1;
  else if (w==XtNameToWidget(d->widget,"*F")) d->Mode=2;
  else if (w==XtNameToWidget(d->widget,"*G")) d->Mode=3;
  else if (w==XtNameToWidget(d->widget,"*H")) d->Mode=4;
  MathDialogSetupItem(d->widget,d);
}


void MathDialogList(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct MathDialog *d;
  XmListCallbackStruct *dd;
  int i,a;
  char *field=NULL;
  char *buf;
  int num,top;
  int *selected;

  d=(struct MathDialog *)client_data;
  dd=(XmListCallbackStruct *)call_data;
  XmListGetSelectedPos(w,&selected,&num);
  XtVaGetValues(w,XmNtopItemPosition,&top,NULL);
  a=dd->item_position;
  for (i=0;i<dd->selected_item_count;i++)
    if (dd->selected_item_positions[i]==a) break;
  if (i!=dd->selected_item_count) {
    if (d->Mode==0) field="math_x";
    else if (d->Mode==1) field="math_y";
    else if (d->Mode==2) field="func_f";
    else if (d->Mode==3) field="func_g";
    else if (d->Mode==4) field="func_h";
    sgetobjfield(d->Obj,a-1,field,NULL,&buf,FALSE,FALSE,FALSE);
    MathTextDialog(&DlgMathText,buf);
    if (DialogExecute(d->widget,&DlgMathText)==IDOK) {
      for (i=0;i<num;i++) {
        a=selected[i]-1;
        sputobjfield(d->Obj,a,field,DlgMathText.math);
        AddMathList(buf);
        NgraphApp.Changed=TRUE;
      }
    }
    XtFree(DlgMathText.math);
    memfree(buf);
  }
  MathDialogSetupItem(d->widget,d);
  XtVaSetValues(w,XmNselectionPolicy,XmMULTIPLE_SELECT,NULL);
  for (i=0;i<num;i++)
    XmListSelectPos(w,selected[i],FALSE);
  XtVaSetValues(w,XmNselectionPolicy,XmEXTENDED_SELECT,NULL);
  XtVaSetValues(w,XmNtopItemPosition,top,NULL);
  if (num!=0) XtFree((char *)selected);
}

void MathDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rb,button,list;
  struct MathDialog *d;

  d=(struct MathDialog *)data;

  if (makewidget) {

    XtUnmanageChild(XmMessageBoxGetChild(w,XmDIALOG_CANCEL_BUTTON));
    ac=0;
    XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
    XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

    ac=0;
    XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
    XtManageChild(rb=XmCreateRadioBox(rc,"rb",al,ac));
    ac=0;
    XtManageChild(button=XmCreateToggleButton(rb,"X",al,ac));
    XtAddCallback(button,XmNarmCallback,MathDialogMode,d);
    XtManageChild(button=XmCreateToggleButton(rb,"Y",al,ac));
    XtAddCallback(button,XmNarmCallback,MathDialogMode,d);
    XtManageChild(button=XmCreateToggleButton(rb,"F",al,ac));
    XtAddCallback(button,XmNarmCallback,MathDialogMode,d);
    XtManageChild(button=XmCreateToggleButton(rb,"G",al,ac));
    XtAddCallback(button,XmNarmCallback,MathDialogMode,d);
    XtManageChild(button=XmCreateToggleButton(rb,"H",al,ac));
    XtAddCallback(button,XmNarmCallback,MathDialogMode,d);

    ac=0;
    XtSetArg(al[ac],XmNlistSizePolicy,XmCONSTANT); ac++;
    XtSetArg(al[ac],XmNscrollBarDisplayPolicy,XmSTATIC); ac++;
    XtSetArg(al[ac],XmNselectionPolicy,XmEXTENDED_SELECT); ac++;
    XtManageChild(list=XmCreateScrolledList(rc,"list",al,ac));
    XtAddCallback(list,XmNdefaultActionCallback,MathDialogList,d);
  }

  MathDialogSetupItem(w,d);
}

void MathDialogClose(Widget w,void *data)
{
}

void MathDialog(struct MathDialog *data,struct objlist *obj)
{
  data->SetupWindow=MathDialogSetup;
  data->CloseWindow=MathDialogClose;
  data->Obj=obj;
  data->Mode=0;
}

void FitLoadDialogDblCB(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct SelectDialog *data;
  XmListCallbackStruct *d;

  data=(struct SelectDialog *)client_data;
  d=(XmListCallbackStruct *)call_data;
  data->ret=IDOK;
  data->CloseWindow(XtParent(w),data);
}

void FitLoadDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  XmString xs;
  char *s;
  struct FitLoadDialog *d;
  int i;
  Widget list;

  d=(struct FitLoadDialog *)data;
  if (makewidget) {
    ac=0;
    XtSetArg(al[ac],XmNlistSizePolicy,XmCONSTANT); ac++;
    XtSetArg(al[ac],XmNscrollBarDisplayPolicy,XmSTATIC); ac++;
    XtSetArg(al[ac],XmNselectionPolicy,XmBROWSE_SELECT); ac++;
    XtManageChild(list=XmCreateScrolledList(w,"list",al,ac));
    XtAddCallback(list,XmNdefaultActionCallback,FitLoadDialogDblCB,data);
  }
  XmListDeleteAllItems(XtNameToWidget(w,"*list"));
  for (i=d->Sid;i<=chkobjlastinst(d->Obj);i++) {
    getobj(d->Obj,"profile",i,0,NULL,&s);
    if (s!=NULL) xs=XmStringCreateLocalized(s);
    else xs=XmStringCreateLocalized("");
    XmListAddItem(XtNameToWidget(w,"*list"),xs,0);
    XmStringFree(xs);
  }
  if (makewidget) {
    XtManageChild(d->widget);
    d->widget=NULL;
    XtVaSetValues(XtNameToWidget(w,"*list"),XmNwidth,200,NULL);
  }
}

void FitLoadDialogClose(Widget w,void *data)
{
  struct FitLoadDialog *d;
  int *selected;
  int num;

  d=(struct FitLoadDialog *)data;
  if (d->ret==IDCANCEL) return;
  XmListGetSelectedPos(XtNameToWidget(w,"*list"),&selected,&num);
  if (num!=0) {
    d->sel=selected[0]-1;
    XtFree((char *)selected);
  } else d->sel=-1;
}

void FitLoadDialog(struct FitLoadDialog *data,
                  struct objlist *obj,int sid)
{
  data->SetupWindow=FitLoadDialogSetup;
  data->CloseWindow=FitLoadDialogClose;
  data->Obj=obj;
  data->Sid=sid;
  data->sel=-1;
}

void FitSaveDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc;
  struct FitSaveDialog *d;
  int i,j;
  char *s;
  XmString xs;

  d=(struct FitSaveDialog *)data;
  if (makewidget) {
    ac=0;
    XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
    XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
    ac=0;
    XtManageChild(XmCreateLabel(rc,"Profile",al,ac));
    ac=0;
    XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
    XtManageChild(XmCreateComboBox(rc,"profile",al,ac));
  }
  XmListDeleteAllItems(GetComboBoxList(w,"*profile"));
  j=0;
  for (i=d->Sid;i<=chkobjlastinst(d->Obj);i++) {
    getobj(d->Obj,"profile",i,0,NULL,&s);
    if (s!=NULL) xs=XmStringCreateLocalized(s);
    else xs=XmStringCreateLocalized("");
    XmListAddItem(GetComboBoxList(w,"*profile"),xs,0);
    XmStringFree(xs);
    j++;
  }
  SetComboBoxVisibleItemCount(w,"*profile",j);
  XtVaSetValues(GetComboBoxText(d->widget,"*profile"),XmNvalue,"",NULL);
}

void FitSaveDialogClose(Widget w,void *data)
{
  struct FitSaveDialog *d;
  char *s;

  d=(struct FitSaveDialog *)data;
  XtVaGetValues(GetComboBoxText(d->widget,"*profile"),XmNvalue,&s,NULL);
  if (s!=NULL) {
    if ((d->Profile=memalloc(strlen(s)+1))!=NULL) strcpy(d->Profile,s);
    XtFree(s);
  }
}

void FitSaveDialog(struct FitSaveDialog *data,struct objlist *obj,int sid)
{
  data->SetupWindow=FitSaveDialogSetup;
  data->CloseWindow=FitSaveDialogClose;
  data->Obj=obj;
  data->Sid=sid;
  data->Profile=NULL;
}

void FitDialogSetupItem(Widget w,struct FitDialog *d,int id)
{
  int a;

  SetListFromObjField(w,"*type",d->Obj,id,"type");
  getobj(d->Obj,"poly_dimension",id,0,NULL,&a);
  XmListDeselectAllItems(GetComboBoxList(w,"*dim"));
  XmListSelectPos(GetComboBoxList(w,"*dim"),a,TRUE);
  SetTextFromObjField(w,"*weight",d->Obj,id,"weight_func");
  SetToggleFromObjField(w,"*Through",d->Obj,id,"through_point");
  SetTextFromObjField(w,"*x",d->Obj,id,"point_x");
  SetTextFromObjField(w,"*y",d->Obj,id,"point_y");
  SetTextFromObjField(w,"*min",d->Obj,id,"min");
  SetTextFromObjField(w,"*max",d->Obj,id,"max");
  SetTextFromObjField(w,"*div",d->Obj,id,"div");
  SetToggleFromObjField(w,"*Interpolation",d->Obj,id,"interpolation");
  SetTextFromObjField(w,"*formula",d->Obj,id,"user_func");
  SetTextFromObjField(w,"*converge",d->Obj,id,"converge");
  SetToggleFromObjField(w,"*Derivatives",d->Obj,id,"derivative");
  SetTextFromObjField(w,"*p0",d->Obj,id,"parameter0");
  SetTextFromObjField(w,"*p1",d->Obj,id,"parameter1");
  SetTextFromObjField(w,"*p2",d->Obj,id,"parameter2");
  SetTextFromObjField(w,"*p3",d->Obj,id,"parameter3");
  SetTextFromObjField(w,"*p4",d->Obj,id,"parameter4");
  SetTextFromObjField(w,"*p5",d->Obj,id,"parameter5");
  SetTextFromObjField(w,"*p6",d->Obj,id,"parameter6");
  SetTextFromObjField(w,"*p7",d->Obj,id,"parameter7");
  SetTextFromObjField(w,"*p8",d->Obj,id,"parameter8");
  SetTextFromObjField(w,"*p9",d->Obj,id,"parameter9");
  SetTextFromObjField(w,"*d0",d->Obj,id,"derivative0");
  SetTextFromObjField(w,"*d1",d->Obj,id,"derivative1");
  SetTextFromObjField(w,"*d2",d->Obj,id,"derivative2");
  SetTextFromObjField(w,"*d3",d->Obj,id,"derivative3");
  SetTextFromObjField(w,"*d4",d->Obj,id,"derivative4");
  SetTextFromObjField(w,"*d5",d->Obj,id,"derivative5");
  SetTextFromObjField(w,"*d6",d->Obj,id,"derivative6");
  SetTextFromObjField(w,"*d7",d->Obj,id,"derivative7");
  SetTextFromObjField(w,"*d8",d->Obj,id,"derivative8");
  SetTextFromObjField(w,"*d9",d->Obj,id,"derivative9");
}

void FitDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FitDialog *d;

  d=(struct FitDialog *)client_data;
  d->ret=IDDELETE;
}

char *FitCB(struct objlist *obj,int id)
{
  char *valstr,*s;

  if ((s=(char *)memalloc(128))==NULL) return NULL;
  sgetobjfield(obj,id,"type",NULL,&valstr,FALSE,FALSE,FALSE);
  sprintf(s,"%-5d %.100s",id,valstr);
  memfree(valstr);
  return s;
}

void FitDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FitDialog *d;
  int sel;

  d=(struct FitDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,FitCB))!=-1) 
    FitDialogSetupItem(d->widget,d,sel);
}

int FitDialogLoadConfig(struct FitDialog *d,int errmes)
{
  int lastid;
  int newid;
  struct objlist *shell;
  struct narray sarray;
  char *argv[2];
  char *file;

  lastid=chkobjlastinst(d->Obj);
  if (lastid==d->Lastid) {
    if ((file=searchscript(FITSAVE))==NULL) {
      if (errmes) MessageBox(TopLevel,"Setting file not found.",FITSAVE,MB_OK);
      return FALSE;
    }
    if ((shell=chkobject("shell"))==NULL) return FALSE;
    newid=newobj(shell);
    if (newid<0) {
      memfree(file);
      return FALSE;
    }
    arrayinit(&sarray,sizeof(char *));
    changefilename(file);
    if (arrayadd(&sarray,&file)==NULL) {
      memfree(file);
      arraydel2(&sarray);
      return FALSE;
    }
    argv[0]=(char *)&sarray;
    argv[1]=NULL;
    exeobj(shell,"shell",newid,1,argv);
    arraydel2(&sarray);
    delobj(shell,newid);
  }
  return TRUE;
}

void FitDialogLoad(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FitDialog *d;
  int lastid,id;

  d=(struct FitDialog *)client_data;
  if (!FitDialogLoadConfig(d,TRUE)) return;
  lastid=chkobjlastinst(d->Obj);
  if ((d->Lastid<0) || (lastid==d->Lastid)) {
    MessageBox(TopLevel,"No settings.",FITSAVE,MB_OK);
    return;
  }
  FitLoadDialog(&DlgFitLoad,d->Obj,d->Lastid+1);
  if ((DialogExecute(d->widget,&DlgFitLoad)==IDOK) && (DlgFitLoad.sel>=0)) {
    id=DlgFitLoad.sel+d->Lastid+1;
    FitDialogSetupItem(d->widget,d,id);
  }
}

void FitDialogSave(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FitDialog *d;
  int i,id,a,len;
  char *s;
  char *ngpfile;
  int error;
  HANDLE hFile;
  int *selected,num;

  d=(struct FitDialog *)client_data;
  if (!FitDialogLoadConfig(d,FALSE)) return;
  FitSaveDialog(&DlgFitSave,d->Obj,d->Lastid+1);
  if (DialogExecute(d->widget,&DlgFitSave)==IDOK) {
    for (i=d->Lastid+1;i<=chkobjlastinst(d->Obj);i++) {
      getobj(d->Obj,"profile",i,0,NULL,&s);
      if (strcmp(s,DlgFitSave.Profile)==0) {
        if (MessageBox(TopLevel,"Overwrite existing setting?","Confirm",
                       MB_YESNO)!=IDYES) return;
        id=i;
        break;
      }
    }
    if (i>chkobjlastinst(d->Obj)) id=newobj(d->Obj);
    if (putobj(d->Obj,"profile",id,DlgFitSave.Profile)==-1) return;
    if (SetObjFieldFromList(d->widget,"*type",d->Obj,id,"type")) return;
    XmListGetSelectedPos(GetComboBoxList(d->widget,"*dim"),&selected,&num);
    if (num!=0) {
      a=selected[0];
      XtFree((char *)selected);
      if (a!=0) {
        if (putobj(d->Obj,"poly_dimension",id,&a)==-1) return;
      }
    }
    if (SetObjFieldFromText(d->widget,"*weight",d->Obj,id,"weight_func"))
      return;
    if (SetObjFieldFromToggle(d->widget,"*Through",d->Obj,id,"through_point"))
      return;
    if (SetObjFieldFromText(d->widget,"*x",d->Obj,id,"point_x")) return;
    if (SetObjFieldFromText(d->widget,"*y",d->Obj,id,"point_y")) return;
    if (SetObjFieldFromText(d->widget,"*min",d->Obj,id,"min")) return;
    if (SetObjFieldFromText(d->widget,"*max",d->Obj,id,"max")) return;
    if (SetObjFieldFromText(d->widget,"*div",d->Obj,id,"div")) return;
    if (SetObjFieldFromToggle(d->widget,"*Interpolation",d->Obj,id,
        "interpolation")) return;
    if (SetObjFieldFromText(d->widget,"*formula",d->Obj,id,"user_func"))
      return;
    if (SetObjFieldFromToggle(d->widget,"*Derivatives",d->Obj,id,"derivative"))
      return;
    if (SetObjFieldFromText(d->widget,"*converge",d->Obj,id,"converge"))
      return;
    if (SetObjFieldFromText(d->widget,"*p0",d->Obj,id,"parameter0")) return;
    if (SetObjFieldFromText(d->widget,"*p1",d->Obj,id,"parameter1")) return;
    if (SetObjFieldFromText(d->widget,"*p2",d->Obj,id,"parameter2")) return;
    if (SetObjFieldFromText(d->widget,"*p3",d->Obj,id,"parameter3")) return;
    if (SetObjFieldFromText(d->widget,"*p4",d->Obj,id,"parameter4")) return;
    if (SetObjFieldFromText(d->widget,"*p5",d->Obj,id,"parameter5")) return;
    if (SetObjFieldFromText(d->widget,"*p6",d->Obj,id,"parameter6")) return;
    if (SetObjFieldFromText(d->widget,"*p7",d->Obj,id,"parameter7")) return;
    if (SetObjFieldFromText(d->widget,"*p8",d->Obj,id,"parameter8")) return;
    if (SetObjFieldFromText(d->widget,"*p9",d->Obj,id,"parameter9")) return;
    if (SetObjFieldFromText(d->widget,"*d0",d->Obj,id,"derivative0")) return;
    if (SetObjFieldFromText(d->widget,"*d1",d->Obj,id,"derivative1")) return;
    if (SetObjFieldFromText(d->widget,"*d2",d->Obj,id,"derivative2")) return;
    if (SetObjFieldFromText(d->widget,"*d3",d->Obj,id,"derivative3")) return;
    if (SetObjFieldFromText(d->widget,"*d4",d->Obj,id,"derivative4")) return;
    if (SetObjFieldFromText(d->widget,"*d5",d->Obj,id,"derivative5")) return;
    if (SetObjFieldFromText(d->widget,"*d6",d->Obj,id,"derivative6")) return;
    if (SetObjFieldFromText(d->widget,"*d7",d->Obj,id,"derivative7")) return;
    if (SetObjFieldFromText(d->widget,"*d8",d->Obj,id,"derivative8")) return;
    if (SetObjFieldFromText(d->widget,"*d9",d->Obj,id,"derivative9")) return;
    if ((ngpfile=getscriptname(FITSAVE))==NULL) return;
    error=FALSE;
    hFile=nopen(ngpfile,O_CREAT|O_TRUNC|O_RDWR,NFMODE);
    for (i=d->Lastid+1;i<=chkobjlastinst(d->Obj);i++) {
      getobj(d->Obj,"save",i,0,NULL,&s);
      len=strlen(s);
      if (len!=nwrite(hFile,s,len)) error=TRUE;
      if (nwrite(hFile,"\n",1)!=1) error=TRUE;
    }
    nclose(hFile);
    if (error) MessageBox(TopLevel,"I/O error: Write","Error:",MB_OK);
    memfree(ngpfile);
  }
}

void FitDialogResult(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FitDialog *d;
  char buf[1024];
  int type,num;
  double derror,correlation;
  double coe[10];
  char *equation;
  int i,j,dim,dimension;
  int maxdim,need2pass;
  struct narray needarray;
  char *math,*code;
  int *needdata,tbl[10];
  char *inst;

  d=(struct FitDialog *)client_data;
  if ((inst=chkobjinst(d->Obj,d->Id))==NULL) return;
  if (_getobj(d->Obj,"type",inst,&type)) return;
  if (_getobj(d->Obj,"poly_dimension",inst,&dimension)) return;
  if (_getobj(d->Obj,"number",inst,&num)) return;
  if (_getobj(d->Obj,"error",inst,&derror)) return;
  if (_getobj(d->Obj,"correlation",inst,&correlation)) return;
  if (_getobj(d->Obj,"%00",inst,&(coe[0]))) return;
  if (_getobj(d->Obj,"%01",inst,&(coe[1]))) return;
  if (_getobj(d->Obj,"%02",inst,&(coe[2]))) return;
  if (_getobj(d->Obj,"%03",inst,&(coe[3]))) return;
  if (_getobj(d->Obj,"%04",inst,&(coe[4]))) return;
  if (_getobj(d->Obj,"%05",inst,&(coe[5]))) return;
  if (_getobj(d->Obj,"%06",inst,&(coe[6]))) return;
  if (_getobj(d->Obj,"%07",inst,&(coe[7]))) return;
  if (_getobj(d->Obj,"%08",inst,&(coe[8]))) return;
  if (_getobj(d->Obj,"%09",inst,&(coe[9]))) return;
  if (_getobj(d->Obj,"equation",inst,&equation)) return;
  if (_getobj(d->Obj,"user_func",inst,&math)) return;
  if (equation==NULL) {
    sprintf(buf,"Undefined");
  } else if (type!=4) {
    i=0;
    if (type==0) dim=dimension+1;
    else dim=2;
    if (type==0) i+=sprintf(buf+i,"Eq: %%0i*X^i (i=0-%d)\n\n",dim-1);
    else if (type==1) i+=sprintf(buf+i,"Eq: exp(%%00)*X^%%01\n\n");
    else if (type==2) i+=sprintf(buf+i,"Eq: exp(%%01*X+%%00)\n\n");
    else if (type==3) i+=sprintf(buf+i,"Eq: %%01*Ln(X)+%%00\n\n");
    for (j=0;j<dim;j++)
      i+=sprintf(buf+i,"       %%0%d = %.7e\n",j,coe[j]);
    i+=sprintf(buf+i,"\n");
    i+=sprintf(buf+i,"    points = %d\n",num);
    i+=sprintf(buf+i,"    <DY^2> = %.7e\n",derror);
    if (correlation>=0)
      i+=sprintf(buf+i,"|r| or |R| = %.7e\n",correlation);
    else
      i+=sprintf(buf+i,"|r| or |R| = -------------\n");
   } else {
    arrayinit(&needarray,sizeof(int));
    mathcode(math,&code,&needarray,NULL,&maxdim,&need2pass,
             TRUE,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE);
    memfree(code);
    dim=arraynum(&needarray);
    needdata=(int *)arraydata(&needarray);
    for (i=0;i<dim;i++) tbl[i]=needdata[i];
    arraydel(&needarray);
    i=0;
    i+=sprintf(buf+i,"Eq: User defined\n\n");
    for (j=0;j<dim;j++)
      i+=sprintf(buf+i,"       %%0%d = %.7e\n",tbl[j],coe[tbl[j]]);
    i+=sprintf(buf+i,"\n");
    i+=sprintf(buf+i,"    points = %d\n",num);
    i+=sprintf(buf+i,"    <DY^2> = %.7e\n",derror);
    if (correlation>=0)
      i+=sprintf(buf+i,"|r| or |R| = %.7e\n",correlation);
    else
      i+=sprintf(buf+i,"|r| or |R| = -------------\n");
  }
  MessageBox(TopLevel,buf,"Fitting Results",MB_OK);
}

int FitDialogApply(Widget w,struct FitDialog *d)
{
  int a;
  int *selected,num;

  if (SetObjFieldFromList(w,"*type",d->Obj,d->Id,"type")) return FALSE;
  XmListGetSelectedPos(GetComboBoxList(w,"*dim"),&selected,&num);
  if (num!=0) {
    a=selected[0];
    XtFree((char *)selected);
    if (a!=0) {
      if (putobj(d->Obj,"poly_dimension",d->Id,&a)==-1) return FALSE;
    }
  }
  if (SetObjFieldFromText(w,"*weight",d->Obj,d->Id,"weight_func"))
    return FALSE;
  if (SetObjFieldFromToggle(w,"*Through",d->Obj,d->Id,"through_point"))
    return FALSE;
  if (SetObjFieldFromText(w,"*x",d->Obj,d->Id,"point_x")) return FALSE;
  if (SetObjFieldFromText(w,"*y",d->Obj,d->Id,"point_y")) return FALSE;
  if (SetObjFieldFromText(w,"*min",d->Obj,d->Id,"min")) return FALSE;
  if (SetObjFieldFromText(w,"*max",d->Obj,d->Id,"max")) return FALSE;
  if (SetObjFieldFromText(w,"*div",d->Obj,d->Id,"div")) return FALSE;
  if (SetObjFieldFromToggle(w,"*Interpolation",d->Obj,d->Id,"interpolation"))
     return FALSE;
  if (SetObjFieldFromText(w,"*formula",d->Obj,d->Id,"user_func"))
    return FALSE;
  if (SetObjFieldFromToggle(w,"*Derivatives",d->Obj,d->Id,"derivative"))
     return FALSE;
  if (SetObjFieldFromText(w,"*converge",d->Obj,d->Id,"converge")) return FALSE;
  if (SetObjFieldFromText(w,"*p0",d->Obj,d->Id,"parameter0")) return FALSE;
  if (SetObjFieldFromText(w,"*p1",d->Obj,d->Id,"parameter1")) return FALSE;
  if (SetObjFieldFromText(w,"*p2",d->Obj,d->Id,"parameter2")) return FALSE;
  if (SetObjFieldFromText(w,"*p3",d->Obj,d->Id,"parameter3")) return FALSE;
  if (SetObjFieldFromText(w,"*p4",d->Obj,d->Id,"parameter4")) return FALSE;
  if (SetObjFieldFromText(w,"*p5",d->Obj,d->Id,"parameter5")) return FALSE;
  if (SetObjFieldFromText(w,"*p6",d->Obj,d->Id,"parameter6")) return FALSE;
  if (SetObjFieldFromText(w,"*p7",d->Obj,d->Id,"parameter7")) return FALSE;
  if (SetObjFieldFromText(w,"*p8",d->Obj,d->Id,"parameter8")) return FALSE;
  if (SetObjFieldFromText(w,"*p9",d->Obj,d->Id,"parameter9")) return FALSE;
  if (SetObjFieldFromText(w,"*d0",d->Obj,d->Id,"derivative0")) return FALSE;
  if (SetObjFieldFromText(w,"*d1",d->Obj,d->Id,"derivative1")) return FALSE;
  if (SetObjFieldFromText(w,"*d2",d->Obj,d->Id,"derivative2")) return FALSE;
  if (SetObjFieldFromText(w,"*d3",d->Obj,d->Id,"derivative3")) return FALSE;
  if (SetObjFieldFromText(w,"*d4",d->Obj,d->Id,"derivative4")) return FALSE;
  if (SetObjFieldFromText(w,"*d5",d->Obj,d->Id,"derivative5")) return FALSE;
  if (SetObjFieldFromText(w,"*d6",d->Obj,d->Id,"derivative6")) return FALSE;
  if (SetObjFieldFromText(w,"*d7",d->Obj,d->Id,"derivative7")) return FALSE;
  if (SetObjFieldFromText(w,"*d8",d->Obj,d->Id,"derivative8")) return FALSE;
  if (SetObjFieldFromText(w,"*d9",d->Obj,d->Id,"derivative9")) return FALSE;
  NgraphApp.Changed=TRUE;
  return TRUE;
}

void FitDialogDraw(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FitDialog *d;

  d=(struct FitDialog *)client_data;
  if (!FitDialogApply(d->widget,d)) return;
  FitDialogSetupItem(d->widget,d,d->Id);
  Draw(FALSE);
}

void FitDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,rc3,rc4,frame,button;
  struct FitDialog *d;
  XmString xs;
  char title[20];
  char **enumlist;
  int i,j;
  char mes[10];

  d=(struct FitDialog *)data;
  sprintf(title,"Fit %d",d->Id);
  xs=XmStringCreateLocalized(title);
  XtVaSetValues(w,XmNdialogTitle,xs,NULL);
  XmStringFree(xs);
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Delete",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FitDialogDelete,d); 
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FitDialogCopy,d); 

  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Load",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FitDialogLoad,d); 
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Save",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FitDialogSave,d); 

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"fm1",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(frame,"fm1rc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"rc1",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"typerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Type",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc4,"type",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"dimrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Dim",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc4,"dim",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"rc2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"throughrc",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc4,"Through",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"X",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc4,"x",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Y",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc4,"y",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"weightrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Weight",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc4,"weight",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"fm2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(frame,"fm2rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Min",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"min",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Max",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"max",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Div",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"div",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"Interpolation",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"fm3",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(frame,"fm3rc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"formularc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Formula",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"formula",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"convergerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Converge",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"converge",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc3,"Derivatives",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"p0rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"P0",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"p0",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"D0",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"d0",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"p1rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"P1",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"p1",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"D1",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"d1",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"p2rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"P2",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"p2",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"D2",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"d2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"p3rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"P3",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"p3",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"D3",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"d3",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"p4rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"P4",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"p4",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"D4",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"d4",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"p5rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"P5",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"p5",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"D5",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"d5",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"p6rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"P6",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"p6",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"D6",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"d6",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"p7rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"P7",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"p7",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"D7",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"d7",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"p8rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"P8",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"p8",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"D8",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"d8",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"p9rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"P9",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"p9",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"D9",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"d9",al,ac));

  enumlist=(char **)chkobjarglist(d->Obj,"type");
  for (j=0;enumlist[j]!=NULL;j++) {
    xs=XmStringCreateLocalized(enumlist[j]);
    XmListAddItem(GetComboBoxList(w,"*type"),xs,0);
    XmStringFree(xs);
  }
  for (i=1;i<10;i++) {
    sprintf(mes,"%d",i);
    xs=XmStringCreateLocalized(mes);
    XmListAddItem(GetComboBoxList(w,"*dim"),xs,0);
    XmStringFree(xs);
  }

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"rc3",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Result",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FitDialogResult,d); 
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Draw",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FitDialogDraw,d); 
  }


  FitDialogSetupItem(w,d,d->Id);
}

void FitDialogClose(Widget w,void *data)
{
  struct FitDialog *d;
  int ret;
  int i,lastid;

  d=(struct FitDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (!FitDialogApply(w,d)) return;
  d->ret=ret;
  lastid=chkobjlastinst(d->Obj);
  for (i=lastid;i>d->Lastid;i--) delobj(d->Obj,i);
}

void FitDialog(struct FitDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=FitDialogSetup;
  data->CloseWindow=FitDialogClose;
  data->Obj=obj;
  data->Id=id;
  data->Lastid=chkobjlastinst(obj);
}

void FileMoveDialogSetupItem(Widget w,struct FileMoveDialog *d,int id)
{
  int j,movenum,line;
  double x,y;
  struct narray *move,*movex,*movey;
  char buf[128];
  XmString xs;

  getobj(d->Obj,"move_data",d->Id,0,NULL,&move);
  getobj(d->Obj,"move_data_x",d->Id,0,NULL,&movex);
  getobj(d->Obj,"move_data_y",d->Id,0,NULL,&movey);
  movenum=arraynum(move);
  if (arraynum(movex)<movenum) movenum=arraynum(movex);
  if (arraynum(movey)<movenum) movenum=arraynum(movey);
  if (movenum>0) {
    for (j=0;j<movenum;j++) {
      line=*(int *)arraynget(move,j);
      x=*(double *)arraynget(movex,j);
      y=*(double *)arraynget(movey,j);
      sprintf(buf,"%8d  %+.15e %+.15e",line,x,y);
      xs=XmStringCreateLocalized(buf);
      XmListAddItem(XtNameToWidget(w,"*list"),xs,0);
      XmStringFree(xs);
    }
  }
}

void FileMoveDialogAdd(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileMoveDialog *d;
  int a;
  double x,y;
  char *buf,buf2[128];
  char *endptr;
  XmString xs;

  d=(struct FileMoveDialog *)client_data;
  XtVaGetValues(XtNameToWidget(d->widget,"*line"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]=='\0') {
    XtFree(buf);
    XtVaGetValues(XtNameToWidget(d->widget,"*x"),XmNvalue,&buf,NULL);
    x=strtod(buf,&endptr);
    if (endptr[0]=='\0') {
      XtFree(buf);
      XtVaGetValues(XtNameToWidget(d->widget,"*y"),XmNvalue,&buf,NULL);
      y=strtod(buf,&endptr);
      if (endptr[0]=='\0') {
        XtFree(buf);
        sprintf(buf2,"%8d  %+.15e %+.15e",a,x,y);
        xs=XmStringCreateLocalized(buf2);
        XmListAddItem(XtNameToWidget(d->widget,"*list"),xs,0);
        XmStringFree(xs);
      } else XtFree(buf);
    } else XtFree(buf);
  } else XtFree(buf);
}

void FileMoveDialogRemove(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileMoveDialog *d;
  int num;
  int *selected;

  d=(struct FileMoveDialog *)client_data;
  XmListGetSelectedPos(XtNameToWidget(d->widget,"*list"),
                       &selected,&num);
  if (num!=0) {
    XmListDeletePositions(XtNameToWidget(d->widget,"*list"),selected,num);
    XtFree((char *)selected);
  }
}

void FileMoveDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,rc3,button;
  struct FileMoveDialog *d;
  XmString xs;

  d=(struct FileMoveDialog *)data;

  if (makewidget) {
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"rc2",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"linerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Line",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"line",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"xrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"X",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"x",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"yrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Y",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"y",al,ac));

  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Add",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileMoveDialogAdd,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Remove",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileMoveDialogRemove,d);

  ac=0;
  XtSetArg(al[ac],XmNlistSizePolicy,XmCONSTANT); ac++;
  XtSetArg(al[ac],XmNscrollBarDisplayPolicy,XmSTATIC); ac++;
  XtSetArg(al[ac],XmNselectionPolicy,XmEXTENDED_SELECT); ac++;
  XtManageChild(XmCreateScrolledList(rc,"list",al,ac));
  xs=XmStringCreateLocalized(
  "                                                        ");
  XmListAddItem(XtNameToWidget(w,"*list"),xs,0);
  XmStringFree(xs);

  XtManageChild(d->widget);
  XmListDeletePos(XtNameToWidget(w,"*list"),1);
  }

  FileMoveDialogSetupItem(w,d,d->Id);

  if (makewidget) d->widget=NULL;
}

void FileMoveDialogClose(Widget w,void *data)
{
  struct FileMoveDialog *d;
  int ret;
  int i,j,count,movenum,line,a;
  double x,y;
  struct narray *move,*movex,*movey;
  char *buf,*buf2;
  char *endptr;
  XmString *xslist;

  d=(struct FileMoveDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  getobj(d->Obj,"move_data",d->Id,0,NULL,&move);
  getobj(d->Obj,"move_data_x",d->Id,0,NULL,&movex);
  getobj(d->Obj,"move_data_y",d->Id,0,NULL,&movey);
  if (move!=NULL) {
    putobj(d->Obj,"move_data",d->Id,NULL);
    move=NULL;
  }
  if (movex!=NULL) {
    putobj(d->Obj,"move_data_x",d->Id,NULL);
    movex=NULL;
  }
  if (movey!=NULL) {
    putobj(d->Obj,"move_data_y",d->Id,NULL);
    movey=NULL;
  }
  XtVaGetValues(XtNameToWidget(w,"*list"),XmNitemCount,&count,
                                          XmNitems,&xslist,NULL);
  for (i=0;i<count;i++) {
    if (XmStringGetLtoR(xslist[i],XmFONTLIST_DEFAULT_TAG,&buf)) {
      buf2=buf;
      a=strtol(buf2,&endptr,10);
      buf2=endptr;
      x=strtod(buf2,&endptr);
      buf2=endptr;
      y=strtod(buf2,&endptr);
      XtFree(buf);
      if (move==NULL) move=arraynew(sizeof(int));
      if (movex==NULL) movex=arraynew(sizeof(double));
      if (movey==NULL) movey=arraynew(sizeof(double));
      movenum=arraynum(move);
      if (arraynum(movex)<movenum) movenum=arraynum(movex);
      if (arraynum(movey)<movenum) movenum=arraynum(movey);
      for (j=0;j<movenum;j++) {
        line=*(int *)arraynget(move,j);
        if (line==a) break;
      }
      if (j==movenum) {
        arrayadd(move,&a);
        arrayadd(movex,&x);
        arrayadd(movey,&y);
      }
    }
  }
  putobj(d->Obj,"move_data",d->Id,move);
  putobj(d->Obj,"move_data_x",d->Id,movex);
  putobj(d->Obj,"move_data_y",d->Id,movey);
  d->ret=ret;
}

void FileMoveDialog(struct FileMoveDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=FileMoveDialogSetup;
  data->CloseWindow=FileMoveDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void FileMaskDialogSetupItem(Widget w,struct FileMaskDialog *d,int id)
{
  int line,j,masknum;
  struct narray *mask;
  char buf[20];
  XmString xs;

  XmListDeleteAllItems(XtNameToWidget(w,"*list"));
  getobj(d->Obj,"mask",d->Id,0,NULL,&mask);
  if ((masknum=arraynum(mask))>0) {
    for (j=0;j<masknum;j++) {
      line=*(int *)arraynget(mask,j);
      sprintf(buf,"%8d",line);
      xs=XmStringCreateLocalized(buf);
      XmListAddItem(XtNameToWidget(w,"*list"),xs,0);
      XmStringFree(xs);
    }
  } 
}

void FileMaskDialogAdd(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileMaskDialog *d;
  int a;
  char *buf,buf2[20];
  char *endptr;
  XmString xs;

  d=(struct FileMaskDialog *)client_data;
  XtVaGetValues(XtNameToWidget(d->widget,"*line"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]=='\0') {
    sprintf(buf2,"%8d",a);
    xs=XmStringCreateLocalized(buf);
    XmListAddItem(XtNameToWidget(d->widget,"*list"),xs,0);
    XmStringFree(xs);
  }
  XtFree(buf);
}

void FileMaskDialogRemove(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileMaskDialog *d;
  int num;
  int *selected;

  d=(struct FileMaskDialog *)client_data;
  XmListGetSelectedPos(XtNameToWidget(d->widget,"*list"),
                       &selected,&num);
  if (num!=0) {
    XmListDeletePositions(XtNameToWidget(d->widget,"*list"),selected,num);
    XtFree((char *)selected);
  }
}

void FileMaskDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,rc3,button;
  struct FileMaskDialog *d;

  d=(struct FileMaskDialog *)data;

  if (makewidget) {
    ac=0;
    XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
    XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

    ac=0;
    XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
    XtManageChild(rc2=XmCreateRowColumn(rc,"rc2",al,ac));

    ac=0;
    XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
    XtManageChild(rc3=XmCreateRowColumn(rc2,"linerc",al,ac));
    ac=0;
    XtManageChild(XmCreateLabel(rc3,"Line",al,ac));
    ac=0;
    XtManageChild(XmCreateTextField(rc3,"line",al,ac));

    ac=0;
    XtManageChild(button=XmCreatePushButton(rc2,"Add",al,ac));
    XtAddCallback(button,XmNdisarmCallback,FileMaskDialogAdd,d);
    ac=0;
    XtManageChild(button=XmCreatePushButton(rc2,"Remove",al,ac));
    XtAddCallback(button,XmNdisarmCallback,FileMaskDialogRemove,d);

    ac=0;
    XtSetArg(al[ac],XmNlistSizePolicy,XmCONSTANT); ac++;
    XtSetArg(al[ac],XmNscrollBarDisplayPolicy,XmSTATIC); ac++;
    XtSetArg(al[ac],XmNselectionPolicy,XmEXTENDED_SELECT); ac++;
    XtManageChild(XmCreateScrolledList(rc,"list",al,ac));
  }

  FileMaskDialogSetupItem(w,d,d->Id);
}

void FileMaskDialogClose(Widget w,void *data)
{
  struct FileMaskDialog *d;
  int ret;
  int i,j,count,masknum,line,a;
  struct narray *mask;
  char *buf;
  char *endptr;
  XmString *xslist;

  d=(struct FileMaskDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  getobj(d->Obj,"mask",d->Id,0,NULL,&mask);
  if (mask!=NULL) {
    putobj(d->Obj,"mask",d->Id,NULL);
    mask=NULL;
  }
  XtVaGetValues(XtNameToWidget(w,"*list"),XmNitemCount,&count,
                                          XmNitems,&xslist,NULL);
  for (i=0;i<count;i++) {
    if (XmStringGetLtoR(xslist[i],XmFONTLIST_DEFAULT_TAG,&buf)) {
      a=strtol(buf,&endptr,10);
      XtFree(buf);
      if (mask==NULL) mask=arraynew(sizeof(int));
      masknum=arraynum(mask);
      for (j=0;j<masknum;j++) {
        line=*(int *)arraynget(mask,j);
        if (line==a) break;
      }
      if (j==masknum) arrayadd(mask,&a);
    }
  }
  putobj(d->Obj,"mask",d->Id,mask);
  d->ret=ret;
}

void FileMaskDialog(struct FileMaskDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=FileMaskDialogSetup;
  data->CloseWindow=FileMaskDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void FileLoadDialogSetupItem(Widget w,struct FileLoadDialog *d,int id)
{
  char *ifs,*s;
  int i;

  SetTextFromObjField(w,"*headskip",d->Obj,id,"head_skip");
  SetTextFromObjField(w,"*readstep",d->Obj,id,"read_step");
  SetTextFromObjField(w,"*finalline",d->Obj,id,"final_line");
  SetTextFromObjField(w,"*remark",d->Obj,id,"remark");
  sgetobjfield(d->Obj,id,"ifs",NULL,&ifs,FALSE,FALSE,FALSE);
  s=nstrnew();
  for (i=0;i<strlen(ifs);i++) {
    if (ifs[i]=='\t') {
      s=nstrccat(s,'\\');
      s=nstrccat(s,'t');
    } else if (ifs[i]=='\\') {
      s=nstrccat(s,'\\');
      s=nstrccat(s,'\\');
    } else s=nstrccat(s,ifs[i]);
  }
  XtVaSetValues(XtNameToWidget(w,"*ifs"),XmNvalue,s,NULL);
  memfree(s);
  memfree(ifs);
  SetToggleFromObjField(w,"*csv",d->Obj,id,"csv");
}

void FileLoadDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileLoadDialog *d;
  int sel;

  d=(struct FileLoadDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,FileCB))!=-1) 
    FileLoadDialogSetupItem(d->widget,d,sel);
}

void FileLoadDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,button;
  struct FileLoadDialog *d;

  d=(struct FileLoadDialog *)data;

  if (makewidget) {
    ac=0;
    XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
    XtAddCallback(button,XmNdisarmCallback,FileLoadDialogCopy,d);

    ac=0;
    XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
    XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

    ac=0;
    XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
    XtManageChild(rc2=XmCreateRowColumn(rc,"rc2",al,ac));
    ac=0;
    XtManageChild(XmCreateLabel(rc2,"Headskip",al,ac));
    ac=0;
    XtManageChild(XmCreateTextField(rc2,"headskip",al,ac));
    ac=0;
    XtManageChild(XmCreateLabel(rc2,"Readstep",al,ac));
    ac=0;
    XtManageChild(XmCreateTextField(rc2,"readstep",al,ac));
    ac=0;
    XtManageChild(XmCreateLabel(rc2,"Finalline",al,ac));
    ac=0;
    XtManageChild(XmCreateTextField(rc2,"finalline",al,ac));

    ac=0;
    XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
    XtManageChild(rc2=XmCreateRowColumn(rc,"rc3",al,ac));
    ac=0;
    XtManageChild(XmCreateLabel(rc2,"Remark",al,ac));
    ac=0;
    XtManageChild(XmCreateTextField(rc2,"remark",al,ac));
    ac=0;
    XtManageChild(XmCreateLabel(rc2,"IFS",al,ac));
    ac=0;
    XtManageChild(XmCreateTextField(rc2,"ifs",al,ac));
    ac=0;
    XtManageChild(XmCreateToggleButton(rc2,"csv",al,ac));
  }

  FileLoadDialogSetupItem(w,d,d->Id);
}

void FileLoadDialogClose(Widget w,void *data)
{
  struct FileLoadDialog *d;
  int ret;
  char *ifs,*s;
  int i;

  d=(struct FileLoadDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromText(w,"*headskip",d->Obj,d->Id,"head_skip")) return;
  if (SetObjFieldFromText(w,"*readstep",d->Obj,d->Id,"read_step")) return;
  if (SetObjFieldFromText(w,"*finalline",d->Obj,d->Id,"final_line")) return;
  if (SetObjFieldFromText(w,"*remark",d->Obj,d->Id,"remark")) return;
  XtVaGetValues(XtNameToWidget(w,"*ifs"),XmNvalue,&ifs,NULL);
  s=nstrnew();
  for (i=0;i<strlen(ifs);i++) {
    if ((ifs[i]=='\\') && (ifs[i+1]=='t')) {
      s=nstrccat(s,0x09);
      i++;
    } else if (ifs[i]=='\\') {
      s=nstrccat(s,'\\');
      i++;
    } else s=nstrccat(s,ifs[i]);
  }
  if (sputobjfield(d->Obj,d->Id,"ifs",s)!=0) {
    memfree(s);
    XtFree(ifs);
    return;
  }
  memfree(s);
  XtFree(ifs);
  if (SetObjFieldFromToggle(w,"*csv",d->Obj,d->Id,"csv")) return;
  d->ret=ret;
}

void FileLoadDialog(struct FileLoadDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=FileLoadDialogSetup;
  data->CloseWindow=FileLoadDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void FileMathDialogSetupItem(Widget w,struct FileMathDialog *d,int id)
{
  int num;
  char **data;

  num=arraynum(menulocal.mathlist);
  data=(char **)arraydata(menulocal.mathlist);
  SetComboList2(w,"*xmath",data,num);
  SetComboList2(w,"*ymath",data,num);
  SetComboList2(w,"*fmath",data,num);
  SetComboList2(w,"*gmath",data,num);
  SetComboList2(w,"*hmath",data,num);
  SetTextFromObjField(w,"*xsmooth",d->Obj,id,"smooth_x");
  SetTextFromObjField(GetComboBoxText(w,"*xmath"),NULL,d->Obj,id,"math_x");
  SetComboListFromObjField(GetComboBoxList(w,"*xmath"),NULL,d->Obj,id,"math_x");
  SetTextFromObjField(w,"*ysmooth",d->Obj,id,"smooth_y");
  SetTextFromObjField(GetComboBoxText(w,"*ymath"),NULL,d->Obj,id,"math_y");
  SetComboListFromObjField(GetComboBoxList(w,"*ymath"),NULL,d->Obj,id,"math_y");
  SetTextFromObjField(GetComboBoxText(w,"*fmath"),NULL,d->Obj,id,"func_f");
  SetComboListFromObjField(GetComboBoxList(w,"*fmath"),NULL,d->Obj,id,"func_f");
  SetTextFromObjField(GetComboBoxText(w,"*gmath"),NULL,d->Obj,id,"func_g");
  SetComboListFromObjField(GetComboBoxList(w,"*gmath"),NULL,d->Obj,id,"func_g");
  SetTextFromObjField(GetComboBoxText(w,"*hmath"),NULL,d->Obj,id,"func_h");
  SetComboListFromObjField(GetComboBoxList(w,"*hmath"),NULL,d->Obj,id,"func_h");
}

void FileMathDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileMathDialog *d;
  int sel;

  d=(struct FileMathDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,FileCB))!=-1) 
    FileMathDialogSetupItem(d->widget,d,sel);
}

void FileMathDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,button;
  struct FileMathDialog *d;

  d=(struct FileMathDialog *)data;
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileMathDialogCopy,d);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"xrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Xsmooth",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"xsmooth",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Xmath",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"xmath",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"yrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Ysmooth",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"ysmooth",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Ymath",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"ymath",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"frc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Fmath",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"fmath",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"grc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Gmath",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"gmath",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"hrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Hmath",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"hmath",al,ac));
  }

  FileMathDialogSetupItem(w,d,d->Id);
}

void FileMathDialogClose(Widget w,void *data)
{
  struct FileMathDialog *d;
  int ret;
  char *s;

  d=(struct FileMathDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  XtVaGetValues(GetComboBoxText(w,"*ymath"),XmNvalue,&s,NULL);
  AddMathList(s);
  XtFree(s);
  XtVaGetValues(GetComboBoxText(w,"*xmath"),XmNvalue,&s,NULL);
  AddMathList(s);
  XtFree(s);
  if (SetObjFieldFromText(w,"*xsmooth",d->Obj,d->Id,"smooth_x")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*xmath"),NULL,
                          d->Obj,d->Id,"math_x")) return;
  if (SetObjFieldFromText(w,"*ysmooth",d->Obj,d->Id,"smooth_y")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*ymath"),NULL,
                          d->Obj,d->Id,"math_y")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*fmath"),NULL,
                          d->Obj,d->Id,"func_f")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*gmath"),NULL,
                          d->Obj,d->Id,"func_g")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*hmath"),NULL,
                          d->Obj,d->Id,"func_h")) return;
  d->ret=ret;
}

void FileMathDialog(struct FileMathDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=FileMathDialogSetup;
  data->CloseWindow=FileMathDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void MarkDialogCB(Widget w,XtPointer client_data,XtPointer call_data)
{
  int i;
  struct MarkDialog *d;
  XmToggleButtonCallbackStruct *dd;

  d=(struct MarkDialog *)client_data;
  dd=(XmToggleButtonCallbackStruct *)call_data;
  for (i=0;i<90;i++) if (w==d->toggle[i]) break;
  d->Type=i;
  d->ret=IDOK;
}

void MarkDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc;
  struct MarkDialog *d;
  int type;
  
  d=(struct MarkDialog *)data;
  if (makewidget) {
    XtUnmanageChild(XmMessageBoxGetChild(w,XmDIALOG_OK_BUTTON));
    XtUnmanageChild(XmMessageBoxGetChild(w,XmDIALOG_CANCEL_BUTTON));
    XtUnmanageChild(XmMessageBoxGetChild(w,XmDIALOG_SEPARATOR));
    ac=0;
    XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
    XtSetArg(al[ac],XmNspacing,0); ac++;
    XtSetArg(al[ac],XmNpacking,XmPACK_COLUMN); ac++;
    XtSetArg(al[ac],XmNnumColumns,9); ac++;
    XtManageChild(rc=XmCreateRadioBox(w,"radio",al,ac));
    for (type=0;type<90;type++) {
      ac=0;
      XtSetArg(al[ac],XmNindicatorOn,XmINDICATOR_NONE); ac++;
      XtSetArg(al[ac],XmNlabelType,XmPIXMAP); ac++; 
      XtSetArg(al[ac],XmNselectPixmap,NgraphApp.markpix[type]); ac++;
      XtSetArg(al[ac],XmNlabelPixmap,NgraphApp.markpix[type]); ac++;
      XtSetArg(al[ac],XmNbackground,white); ac++;
      XtSetArg(al[ac],XmNforeground,black); ac++; 
      XtManageChild(d->toggle[type]=XmCreateToggleButton(rc,NULL,al,ac));
      XtAddCallback(d->toggle[type],XmNdisarmCallback,MarkDialogCB,d);
      XtAddCallback(d->toggle[type],XmNvalueChangedCallback,MarkDialogCB,d);
    }
  }
  XtManageChild(w);
  d->widget=NULL;
  XmProcessTraversal(d->toggle[d->Type],XmTRAVERSE_CURRENT);
}

void MarkDialogClose(Widget w,void *data)
{
}

void MarkDialog(struct MarkDialog *data,int type)
{
  data->SetupWindow=MarkDialogSetup;
  data->CloseWindow=MarkDialogClose;
  data->Type=type;
}

void FileDialogSetupItem(Widget w,struct FileDialog *d,int file,int id)
{
  char *valstr;
  int i,j,a;
  XmString xs;
  struct objlist *aobj;
  int lastinst;
  char *name;

  if (file) {
    SetTextFromObjField(w,"*file",d->Obj,id,"file");
  }
  XmListDeleteAllItems(GetComboBoxList(w,"*xaxis"));
  XmListDeleteAllItems(GetComboBoxList(w,"*yaxis"));
  aobj=getobject("axis");
  lastinst=chkobjlastinst(aobj);
  for (j=0;j<=lastinst;j++) {
    getobj(aobj,"group",j,0,NULL,&name);
    if (name==NULL) name="";
    xs=XmStringCreateLocalized(name);
    XmListAddItem(GetComboBoxList(w,"*xaxis"),xs,0);
    XmListAddItem(GetComboBoxList(w,"*yaxis"),xs,0);
    XmStringFree(xs);
  }
  SetComboBoxVisibleItemCount(w,"*xaxis",j);
  SetComboBoxVisibleItemCount(w,"*yaxis",j);
  SetTextFromObjField(w,"*xcol",d->Obj,id,"x");
  sgetobjfield(d->Obj,id,"axis_x",NULL,&valstr,FALSE,FALSE,FALSE);
  for (i=0;(valstr[i]!='\0') && (valstr[i]!=':');i++);
  if (valstr[i]==':') i++;
  XtVaSetValues(GetComboBoxText(w,"*xaxis"),XmNvalue,valstr+i,NULL);
  memfree(valstr);
  SetTextFromObjField(w,"*ycol",d->Obj,id,"y");
  sgetobjfield(d->Obj,id,"axis_y",NULL,&valstr,FALSE,FALSE,FALSE);
  for (i=0;(valstr[i]!='\0') && (valstr[i]!=':');i++);
  if (valstr[i]==':') i++;
  XtVaSetValues(GetComboBoxText(w,"*yaxis"),XmNvalue,valstr+i,NULL);
  memfree(valstr);
  SetListFromObjField(w,"*type",d->Obj,id,"type");
  SetListFromObjField(w,"*curve",d->Obj,id,"interpolation");
  if (id==d->Id) {
    sgetobjfield(d->Obj,id,"fit",NULL,&valstr,FALSE,FALSE,FALSE);
    for (i=0;(valstr[i]!='\0') && (valstr[i]!=':');i++);
    if (valstr[i]==':') i++;
    xs=XmStringCreateLocalized(valstr+i);
    XtVaSetValues(XtNameToWidget(w,"*fitid"),XmNlabelString,xs,NULL);
    XmStringFree(xs);
    memfree(valstr);
  }

  getobj(d->Obj,"mark_type",id,0,NULL,&a);
  if (a<0) a=89;
  if (a>89) a=89;
  XtVaSetValues(XtNameToWidget(w,"*mark"),XmNlabelPixmap,
                NgraphApp.markpix[a],NULL);
  XtVaSetValues(XtNameToWidget(w,"*mark"),XmNlabelInsensitivePixmap,
                NgraphApp.markpix[a],NULL);
  MarkDialog(&(d->mark),a);
  SetComboList(w,"*size",cbmarksize,CBMARKSIZE);
  SetTextFromObjField(GetComboBoxText(w,"*size"),NULL,d->Obj,id,"mark_size");
  SetComboListFromObjField(GetComboBoxList(w,"*size"),NULL,d->Obj,id,"mark_size");
  SetComboList(w,"*width",cblinewidth,CBLINEWIDTH);
  SetTextFromObjField(GetComboBoxText(w,"*width"),NULL,d->Obj,id,"line_width");
  SetComboListFromObjField(GetComboBoxList(w,"*width"),NULL,d->Obj,id,"line_width");
  SetStyleFromObjField(w,"*style",d->Obj,id,"line_style");
  SetListFromObjField(w,"*join",d->Obj,id,"line_join");
  SetTextFromObjField(w,"*miter",d->Obj,id,"line_miter_limit");
  SetToggleFromObjField(w,"*Clip",d->Obj,id,"data_clip");
  getobj(d->Obj,"R",id,0,NULL,&(d->R));
  getobj(d->Obj,"G",id,0,NULL,&(d->G));
  getobj(d->Obj,"B",id,0,NULL,&(d->B));
  XtVaSetValues(XtNameToWidget(w,"*col1"),XmNbackground,RGB(d->R,d->G,d->B),NULL);
  getobj(d->Obj,"R2",id,0,NULL,&(d->R2));
  getobj(d->Obj,"G2",id,0,NULL,&(d->G2));
  getobj(d->Obj,"B2",id,0,NULL,&(d->B2));
  XtVaSetValues(XtNameToWidget(w,"*col2"),XmNbackground,RGB(d->R2,d->G2,d->B2),NULL);
}

void FileDialogAxisX(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;
  XmComboBoxCallbackStruct *dd;
  char buf[10];
  int a;

  d=(struct FileDialog *)client_data;
  dd=(XmComboBoxCallbackStruct *)call_data;
#ifdef ZEROBASECOMBOBOX
  a=dd->item_position;
#else
  a=dd->item_position-1;
#endif
  if (a<0) return;
  sprintf(buf,"%d",a); 
  XtVaSetValues(GetComboBoxText(d->widget,"*xaxis"),XmNvalue,buf,NULL);
}

void FileDialogAxisY(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;
  XmComboBoxCallbackStruct *dd;
  char buf[10];
  int a;

  d=(struct FileDialog *)client_data;
  dd=(XmComboBoxCallbackStruct *)call_data;
#ifdef ZEROBASECOMBOBOX
  a=dd->item_position;
#else
  a=dd->item_position-1;
#endif
  if (a<0) return;
  sprintf(buf,"%d",a); 
  XtVaSetValues(GetComboBoxText(d->widget,"*yaxis"),XmNvalue,buf,NULL);
}

void FileDialogMark(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;

  d=(struct FileDialog *)client_data;
  DialogExecute(d->widget,&(d->mark));
  XtVaSetValues(w,XmNlabelPixmap,NgraphApp.markpix[d->mark.Type],NULL);
  XtVaSetValues(w,XmNlabelInsensitivePixmap,NgraphApp.markpix[d->mark.Type],NULL);
}

void FileDialogFit(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;
  struct objlist *fitobj,*obj;
  char *fit,*inst;
  int i,idnum,fitid=0,fitoid,ret;
  struct narray iarray;
  char *valstr;

  d=(struct FileDialog *)client_data;
  if ((fitobj=chkobject("fit"))==NULL) return;
  if (getobj(d->Obj,"fit",d->Id,0,NULL,&fit)==-1) return;
  if (fit!=NULL) {
    arrayinit(&iarray,sizeof(int));
    if (getobjilist(fit,&obj,&iarray,FALSE,NULL)) return;
    idnum=arraynum(&iarray);
    if ((obj!=fitobj) || (idnum<1)) {
      if (putobj(d->Obj,"fit",d->Id,NULL)==-1) {
        arraydel(&iarray);
        return;
      }
    } else fitid=*(int *)arraylast(&iarray);
    arraydel(&iarray);
  }
  if (fit==NULL) {
    fitid=newobj(fitobj);
    inst=getobjinst(fitobj,fitid);
    _getobj(fitobj,"oid",inst,&fitoid);
    if ((fit=mkobjlist(fitobj,NULL,fitoid,NULL,TRUE))==NULL) return;
    if (putobj(d->Obj,"fit",d->Id,fit)==-1) {
      memfree(fit);
      return;
    }
  }
  FitDialog(&DlgFit,fitobj,fitid);
  ret=DialogExecute(d->widget,&DlgFit);
  if (ret==IDDELETE) {
    delobj(fitobj,fitid);
    putobj(d->Obj,"fit",d->Id,NULL);
  } else if (ret==IDOK) {
    XmListSelectPos(GetComboBoxList(d->widget,"*type"),19+1,TRUE);
  }
  sgetobjfield(d->Obj,d->Id,"fit",NULL,&valstr,FALSE,FALSE,FALSE);
  for (i=0;(valstr[i]!='\0') && (valstr[i]!=':');i++);
  if (valstr[i]==':') i++;
  XtVaSetValues(XtNameToWidget(d->widget,"*fitid"),XmNvalue,valstr,NULL);
  memfree(valstr);
}

void FileDialogColor1(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;

  d=(struct FileDialog *)client_data;
  GetColor(TopLevel,&d->R,&d->G,&d->B);
  XtVaSetValues(w,XmNbackground,RGB(d->R,d->G,d->B),NULL);
}

void FileDialogColor2(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;

  d=(struct FileDialog *)client_data;
  GetColor(TopLevel,&d->R2,&d->G2,&d->B2);
  XtVaSetValues(w,XmNbackground,RGB(d->R2,d->G2,d->B2),NULL);
}

void FileDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;

  d=(struct FileDialog *)client_data;
  d->ret=IDDELETE;
}

void FileDialogApply(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;

  d=(struct FileDialog *)client_data;
  d->ret=IDFAPPLY;
  d->CloseWindow(d->widget,d);
}

void FileDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;
  int sel;

  d=(struct FileDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,FileCB))!=-1) 
    FileDialogSetupItem(d->widget,d,FALSE,sel);
}

void FileDialogCopyAll(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;
  int sel;
  int j,perm,type;
  char *field;

  d=(struct FileDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,FileCB))!=-1) {
    for (j=0;j<chkobjfieldnum(d->Obj);j++) {
      field=chkobjfieldname(d->Obj,j);
      perm=chkobjperm(d->Obj,field);
      type=chkobjfieldtype(d->Obj,field);
      if ((strcmp2(field,"name")!=0) && (strcmp2(field,"file")!=0)
      && (strcmp2(field,"fit")!=0)
      && ((perm&NREAD)!=0) && ((perm&NWRITE)!=0) && (type<NVFUNC))
        copyobj(d->Obj,field,d->Id,sel);
    }
    FitCopy(d->Obj,d->Id,sel);
    FileDialogSetupItem(d->widget,d,FALSE,d->Id);
    NgraphApp.Changed=TRUE;
  }
}

void FileDialogOption(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;

  d=(struct FileDialog *)client_data;
  exeobj(d->Obj,"load_settings",d->Id,0,NULL);
  FileDialogSetupItem(d->widget,d,FALSE,d->Id);
}

void FileDialogMath(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;

  d=(struct FileDialog *)client_data;
  FileMathDialog(&DlgFileMath,d->Obj,d->Id);
  DialogExecute(d->widget,&DlgFileMath);
}

void FileDialogLoad(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;

  d=(struct FileDialog *)client_data;
  FileLoadDialog(&DlgFileLoad,d->Obj,d->Id);
  DialogExecute(d->widget,&DlgFileLoad);
}

void FileDialogMask(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;

  d=(struct FileDialog *)client_data;
  FileMaskDialog(&DlgFileMask,d->Obj,d->Id);
  DialogExecute(d->widget,&DlgFileMask);
}

void FileDialogMove(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;

  d=(struct FileDialog *)client_data;
  FileMoveDialog(&DlgFileMove,d->Obj,d->Id);
  DialogExecute(d->widget,&DlgFileMove);
}

void FileDialogEdit(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;
  char *name;
  char *argv[3];
  pid_t pid;

  d=(struct FileDialog *)client_data;
  if (menulocal.editor==NULL) return;
  argv[0]=menulocal.editor;
  argv[2]=NULL;
  XtVaGetValues(XtNameToWidget(d->widget,"*file"),XmNvalue,&name,NULL);
  if (name!=NULL) {
    argv[1]=name;
    if ((pid=fork())>=0) {
      if (pid==0) {
        execvp(argv[0],argv);
        exit(1);
      } else arrayadd(&childlist,&pid);
    }
  }
  XtFree(name);
}

void FileDialogType(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileDialog *d;
  XmComboBoxCallbackStruct *dd;
  int type;

  d=(struct FileDialog *)client_data;
  dd=(XmComboBoxCallbackStruct *)call_data;
  XtSetSensitive(XtNameToWidget(d->widget,"*mark"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*curve"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*Mark"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*Curve"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*Color1"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*col1"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*Color2"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*col2"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*style"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*width"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*size"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*miter"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*join"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*Style"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*Width"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*Size"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*Miter"),TRUE);
  XtSetSensitive(XtNameToWidget(d->widget,"*Join"),TRUE);
#ifdef ZEROBASECOMBOBOX
  type=dd->item_position;
#else
  type=dd->item_position-1;
#endif
  switch (type) {
  case 0:
    XtSetSensitive(XtNameToWidget(d->widget,"*curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*join"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Join"),FALSE);
    break;
  case 1:
  case 2:
    XtSetSensitive(XtNameToWidget(d->widget,"*mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Color2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*col2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*size"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Size"),FALSE);
    break;
  case 3:
    XtSetSensitive(XtNameToWidget(d->widget,"*mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Color2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*col2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*size"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Size"),FALSE);
    break;
  case 4:
  case 6:
  case 8:
    XtSetSensitive(XtNameToWidget(d->widget,"*mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Color2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*col2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*size"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*join"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Size"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Join"),FALSE);
    break;
  case 5:
    XtSetSensitive(XtNameToWidget(d->widget,"*mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Color2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*col2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*join"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Join"),FALSE);
    break;
  case 7:
    XtSetSensitive(XtNameToWidget(d->widget,"*mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*size"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*join"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Size"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Join"),FALSE);
    break;
  case 9:
  case 10:
    XtSetSensitive(XtNameToWidget(d->widget,"*mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Color2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*col2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*join"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Join"),FALSE);
    break;
  case 11:
  case 12:
    XtSetSensitive(XtNameToWidget(d->widget,"*mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Color2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*col2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*size"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Size"),FALSE);
    break;
  case 13:
  case 14:
  case 17:
  case 18:
    XtSetSensitive(XtNameToWidget(d->widget,"*mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Color2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*col2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*join"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Join"),FALSE);
    break;
  case 15:
  case 16:
    XtSetSensitive(XtNameToWidget(d->widget,"*mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*join"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Miter"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Join"),FALSE);
    break;
  case 19:
    XtSetSensitive(XtNameToWidget(d->widget,"*mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Mark"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Curve"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Color2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*col2"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*size"),FALSE);
    XtSetSensitive(XtNameToWidget(d->widget,"*Size"),FALSE);
    break;
  }
}

void FileDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,rc3,rc4,rc5,rc6,frame,button,combo;
  struct FileDialog *d;
  XmString xs;
  char title[20];
  int i,j,line,rcode;
  char *argv[2];
  char *s;
  char ch;
  
  d=(struct FileDialog *)data;
  sprintf(title,"Data %d",d->Id);
  xs=XmStringCreateLocalized(title);
  XtVaSetValues(w,XmNdialogTitle,xs,NULL);
  XmStringFree(xs);
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Apply_all",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogApply,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Close",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogDelete,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogCopy,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy_all",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogCopyAll,d);

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"filerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"File",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"file",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Load_settings",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogOption,d);

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"rc2",al,ac));
  ac=0;
  XtManageChild(frame=XmCreateFrame(rc2,"fm",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(frame,"columnrc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"xrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Xcolumn",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc4,"xcol",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Xaxis",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(combo=XmCreateComboBox(rc4,"xaxis",al,ac));
  XtAddCallback(combo,XmNselectionCallback,FileDialogAxisX,d);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"yrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Ycolumn",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc4,"ycol",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Yaxis",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(combo=XmCreateComboBox(rc4,"yaxis",al,ac));
  XtAddCallback(combo,XmNselectionCallback,FileDialogAxisY,d);

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"commentrc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNlistSizePolicy,XmCONSTANT); ac++; 
  XtSetArg(al[ac],XmNscrollBarDisplayPolicy,XmSTATIC); ac++;
  XtManageChild(XmCreateScrolledList(rc3,"comment",al,ac));
  XtVaSetValues(XtNameToWidget(w,"*comment"),XmNwidth,250,
                XmNlistSizePolicy,XmCONSTANT,NULL); 
  xs=XmStringCreateLocalized("012345678901234567890123456789");
  XmListAddItem(XtNameToWidget(w,"*comment"),xs,0);
  XmStringFree(xs);

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"rc3",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc2,"typerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Type",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(combo=XmCreateComboBox(rc4,"type",al,ac));
  XtAddCallback(combo,XmNselectionCallback,FileDialogType,d);
  ac=0;
  XtManageChild(frame=XmCreateFrame(rc4,"typefm",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc6=XmCreateRowColumn(frame,"typerc2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc6,"markrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Mark",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNlabelType,XmPIXMAP); ac++;
  XtSetArg(al[ac],XmNlabelPixmap,NgraphApp.markpix[0]); ac++;
  XtManageChild(button=XmCreateDrawnButton(rc5,"mark",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogMark,d);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc6,"curverc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Curve",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc5,"curve",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc6,"fitrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Fit",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc5,"fit",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogFit,d);
  ac=0;
  xs=XmStringCreateLocalized("      ");
  XtSetArg(al[ac],XmNlabelString,xs); ac++;
  XtManageChild(XmCreateLabel(rc5,"fitid",al,ac));
  XmStringFree(xs); 

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc4,"colorrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Color1",al,ac));
  ac=0;
  XtManageChild(button=XmCreateDrawnButton(rc5,"col1",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogColor1,d);
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Color2",al,ac));
  ac=0;
  XtManageChild(button=XmCreateDrawnButton(rc5,"col2",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogColor2,d);
  ac=0;
  XtManageChild(XmCreateToggleButton(rc5,"Clip",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc2,"pararc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc4,"stylerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Style",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc5,"style",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc4,"widthrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Width",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc5,"width",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc4,"sizerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Size",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc5,"size",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc4,"miterrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Miter",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc5,"miter",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc4,"joinrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Join",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc5,"join",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"buttonrc",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Math",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogMath,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Load",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogLoad,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Mask",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogMask,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Move",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogMove,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Edit",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogEdit,d);
  XtManageChild(d->widget); 

  XtVaSetValues(XtNameToWidget(w,"*commentrc"),XmNresizeWidth,FALSE,
                                               XmNresizeHeight,FALSE,NULL); 
  XtVaSetValues(XtNameToWidget(w,"*typerc"),XmNresizeWidth,FALSE,
                                            XmNresizeHeight,FALSE,NULL);
  XtVaSetValues(XtNameToWidget(w,"*columnrc"),XmNresizeWidth,FALSE,
                                              XmNresizeHeight,FALSE,NULL);
  }

  XmListDeleteAllItems(XtNameToWidget(w,"*comment"));
  line=10;
  argv[0]=(char *)&line;
  argv[1]=NULL;
  rcode=getobj(d->Obj,"head_lines",d->Id,1,argv,&s);
  if ((rcode>=0) && (s!=NULL)) {
    i=0;
    ch='\n';
    while (ch!='\0') {
      for (j=i;(s[j]!='\n') && (s[j]!='\0');j++);
      ch=s[j];
      s[j]='\0';
      xs=XmStringCreateLocalized(s+i);
      XmListAddItem(XtNameToWidget(w,"*comment"),xs,0);
      XmStringFree(xs);
      i=j+1;
    }
  }
  FileDialogSetupItem(w,d,TRUE,d->Id);
  if (makewidget) d->widget=NULL;
}

void FileDialogClose(Widget w,void *data)
{
  struct FileDialog *d;
  int ret;
  char *s,*buf;
  int len;
  
  d=(struct FileDialog *)data;
  if ((d->ret!=IDOK) && (d->ret!=IDFAPPLY)) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromText(w,"*file",d->Obj,d->Id,"file")) return;
  if (SetObjFieldFromText(w,"*xcol",d->Obj,d->Id,"x")) return;
  XtVaGetValues(GetComboBoxText(w,"*xaxis"),XmNvalue,&s,NULL);
  if (s==NULL) len=0;
  else len=strlen(s);
  if ((buf=(char *)memalloc(len+6))!=NULL) {
    strcpy(buf,"axis:");
    if (s!=NULL) strcat(buf,s);
    if (sputobjfield(d->Obj,d->Id,"axis_x",buf)!=0) {
      memfree(buf);
      return;
    }
    memfree(buf);
  }
  XtFree(s);
  if (SetObjFieldFromText(w,"*ycol",d->Obj,d->Id,"y")) return;
  XtVaGetValues(GetComboBoxText(w,"*yaxis"),XmNvalue,&s,NULL);
  if (s==NULL) len=0;
  else len=strlen(s);
  if ((buf=(char *)memalloc(len+6))!=NULL) {
    strcpy(buf,"axis:");
    if (s!=NULL) strcat(buf,s);
    if (sputobjfield(d->Obj,d->Id,"axis_y",buf)!=0) {
      memfree(buf);
      return;
    }
    memfree(buf);
  }
  XtFree(s);
  if (SetObjFieldFromList(w,"*type",d->Obj,d->Id,"type")) return;
  if (SetObjFieldFromList(w,"*curve",d->Obj,d->Id,"interpolation")) return;
  if (putobj(d->Obj,"mark_type",d->Id,&(d->mark.Type))==-1) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*size"),NULL,
      d->Obj,d->Id,"mark_size")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*width"),NULL,
      d->Obj,d->Id,"line_width")) return;
  if (SetObjFieldFromStyle(w,"*style",d->Obj,d->Id,"line_style")) return;
  if (SetObjFieldFromList(w,"*join",d->Obj,d->Id,"line_join")) return;
  if (SetObjFieldFromText(w,"*miter",d->Obj,d->Id,"line_miter_limit")) return;
  if (SetObjFieldFromToggle(w,"*Clip",d->Obj,d->Id,"data_clip")) return;
  if (putobj(d->Obj,"R",d->Id,&(d->R))==-1) return;
  if (putobj(d->Obj,"G",d->Id,&(d->G))==-1) return;
  if (putobj(d->Obj,"B",d->Id,&(d->B))==-1) return;
  if (putobj(d->Obj,"R2",d->Id,&(d->R2))==-1) return;
  if (putobj(d->Obj,"G2",d->Id,&(d->G2))==-1) return;
  if (putobj(d->Obj,"B2",d->Id,&(d->B2))==-1) return;
  d->ret=ret;
}

void FileDialog(struct FileDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=FileDialogSetup;
  data->CloseWindow=FileDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void FileDialogDefSetupItem(Widget w,struct FileDialog *d,int id)
{
  char *valstr;
  int i,j,a;
  XmString xs;
  struct objlist *aobj;
  int lastinst;
  char *name;

  XmListDeleteAllItems(GetComboBoxList(w,"*xaxis"));
  XmListDeleteAllItems(GetComboBoxList(w,"*yaxis"));
  aobj=getobject("axis");
  lastinst=chkobjlastinst(aobj);
  for (j=0;j<=lastinst;j++) {
    getobj(aobj,"group",j,0,NULL,&name);
    if (name==NULL) name="";
    xs=XmStringCreateLocalized(name);
    XmListAddItem(GetComboBoxList(w,"*xaxis"),xs,0);
    XmListAddItem(GetComboBoxList(w,"*yaxis"),xs,0);
    XmStringFree(xs);
  }
  SetComboBoxVisibleItemCount(w,"*xaxis",j);
  SetComboBoxVisibleItemCount(w,"*yaxis",j);
  SetTextFromObjField(w,"*xcol",d->Obj,id,"x");
  sgetobjfield(d->Obj,id,"axis_x",NULL,&valstr,FALSE,FALSE,FALSE);
  for (i=0;(valstr[i]!='\0') && (valstr[i]!=':');i++);
  if (valstr[i]==':') i++;
  XtVaSetValues(GetComboBoxText(w,"*xaxis"),XmNvalue,valstr+i,NULL);
  memfree(valstr);
  SetTextFromObjField(w,"*ycol",d->Obj,id,"y");
  sgetobjfield(d->Obj,id,"axis_y",NULL,&valstr,FALSE,FALSE,FALSE);
  for (i=0;(valstr[i]!='\0') && (valstr[i]!=':');i++);
  if (valstr[i]==':') i++;
  XtVaSetValues(GetComboBoxText(w,"*yaxis"),XmNvalue,valstr+i,NULL);
  memfree(valstr);
  SetListFromObjField(w,"*type",d->Obj,id,"type");
  SetListFromObjField(w,"*curve",d->Obj,id,"interpolation");

  getobj(d->Obj,"mark_type",id,0,NULL,&a);
  if (a<0) a=89;
  if (a>89) a=89;
  XtVaSetValues(XtNameToWidget(w,"*mark"),XmNlabelPixmap,
                NgraphApp.markpix[a],NULL);
  MarkDialog(&(d->mark),a);
  SetComboList(w,"*size",cbmarksize,CBMARKSIZE);
  SetTextFromObjField(GetComboBoxText(w,"*size"),NULL,d->Obj,id,"mark_size");
  SetComboListFromObjField(GetComboBoxList(w,"*size"),NULL,d->Obj,id,"mark_size");
  SetComboList(w,"*width",cblinewidth,CBLINEWIDTH);
  SetTextFromObjField(GetComboBoxText(w,"*width"),NULL,d->Obj,id,"line_width");
  SetComboListFromObjField(GetComboBoxList(w,"*width"),NULL,d->Obj,id,"line_width");
  SetStyleFromObjField(w,"*style",d->Obj,id,"line_style");
  SetListFromObjField(w,"*join",d->Obj,id,"line_join");
  SetTextFromObjField(w,"*miter",d->Obj,id,"line_miter_limit");
  SetToggleFromObjField(w,"*Clip",d->Obj,id,"data_clip");
  getobj(d->Obj,"R",id,0,NULL,&(d->R));
  getobj(d->Obj,"G",id,0,NULL,&(d->G));
  getobj(d->Obj,"B",id,0,NULL,&(d->B));
  XtVaSetValues(XtNameToWidget(w,"*col1"),XmNbackground,RGB(d->R,d->G,d->B),NULL);
  getobj(d->Obj,"R2",id,0,NULL,&(d->R2));
  getobj(d->Obj,"G2",id,0,NULL,&(d->G2));
  getobj(d->Obj,"B2",id,0,NULL,&(d->B2));
  XtVaSetValues(XtNameToWidget(w,"*col2"),XmNbackground,RGB(d->R2,d->G2,d->B2),NULL);
}

void FileDefDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,rc3,rc4,rc5,rc6,frame,button,combo;
  struct FileDialog *d;
  
  d=(struct FileDialog *)data;

  if (makewidget) {
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"rc2",al,ac));
  ac=0;
  XtManageChild(frame=XmCreateFrame(rc2,"fm",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(frame,"columnrc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"xrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Xcolumn",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc4,"xcol",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Xaxis",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(combo=XmCreateComboBox(rc4,"xaxis",al,ac));
  XtAddCallback(combo,XmNselectionCallback,FileDialogAxisX,d);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"yrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Ycolumn",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc4,"ycol",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Yaxis",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(combo=XmCreateComboBox(rc4,"yaxis",al,ac));
  XtAddCallback(combo,XmNselectionCallback,FileDialogAxisY,d);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"commentrc",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"rc3",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc2,"typerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Type",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(combo=XmCreateComboBox(rc4,"type",al,ac));
  ac=0;
  XtManageChild(frame=XmCreateFrame(rc4,"typefm",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc6=XmCreateRowColumn(frame,"typerc2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc6,"markrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Mark",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNlabelType,XmPIXMAP); ac++;
  XtSetArg(al[ac],XmNlabelPixmap,NgraphApp.markpix[0]); ac++;
  XtManageChild(button=XmCreateDrawnButton(rc5,"mark",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogMark,d);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc6,"curverc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Curve",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc5,"curve",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc6,"fitrc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc4,"colorrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Color1",al,ac));
  ac=0;
  XtManageChild(button=XmCreateDrawnButton(rc5,"col1",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogColor1,d);
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Color2",al,ac));
  ac=0;
  XtManageChild(button=XmCreateDrawnButton(rc5,"col2",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogColor2,d);
  ac=0;
  XtManageChild(XmCreateToggleButton(rc5,"Clip",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc2,"pararc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc4,"stylerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Style",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc5,"style",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc4,"widthrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Width",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc5,"width",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc4,"sizerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Size",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc5,"size",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc4,"miterrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Miter",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc5,"miter",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc5=XmCreateRowColumn(rc4,"joinrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc5,"Join",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc5,"join",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"buttonrc",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Math",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogMath,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Load",al,ac));
  XtAddCallback(button,XmNdisarmCallback,FileDialogLoad,d);
  }
  FileDialogDefSetupItem(w,d,d->Id); 
}

void FileDefDialogClose(Widget w,void *data)
{
  struct FileDialog *d;
  int ret;
  char *s,*buf;
  int len;
  
  d=(struct FileDialog *)data;
  if ((d->ret!=IDOK) && (d->ret!=IDFAPPLY)) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromText(w,"*xcol",d->Obj,d->Id,"x")) return;
  XtVaGetValues(GetComboBoxText(w,"*xaxis"),XmNvalue,&s,NULL);
  if (s==NULL) len=0;
  else len=strlen(s);
  if ((buf=(char *)memalloc(len+6))!=NULL) {
    strcpy(buf,"axis:");
    if (s!=NULL) strcat(buf,s);
    if (sputobjfield(d->Obj,d->Id,"axis_x",buf)!=0) {
      memfree(buf);
      return;
    }
    memfree(buf);
  }
  XtFree(s);
  if (SetObjFieldFromText(w,"*ycol",d->Obj,d->Id,"y")) return;
  XtVaGetValues(GetComboBoxText(w,"*yaxis"),XmNvalue,&s,NULL);
  if (s==NULL) len=0;
  else len=strlen(s);
  if ((buf=(char *)memalloc(len+6))!=NULL) {
    strcpy(buf,"axis:");
    if (s!=NULL) strcat(buf,s);
    if (sputobjfield(d->Obj,d->Id,"axis_y",buf)!=0) {
      memfree(buf);
      return;
    }
    memfree(buf);
  }
  XtFree(s);
  if (SetObjFieldFromList(w,"*type",d->Obj,d->Id,"type")) return;
  if (SetObjFieldFromList(w,"*curve",d->Obj,d->Id,"interpolation")) return;
  if (putobj(d->Obj,"mark_type",d->Id,&(d->mark.Type))==-1) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*size"),NULL,
      d->Obj,d->Id,"mark_size")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*width"),NULL,
      d->Obj,d->Id,"line_width")) return;
  if (SetObjFieldFromStyle(w,"*style",d->Obj,d->Id,"line_style")) return;
  if (SetObjFieldFromList(w,"*join",d->Obj,d->Id,"line_join")) return;
  if (SetObjFieldFromText(w,"*miter",d->Obj,d->Id,"line_miter_limit")) return;
  if (SetObjFieldFromToggle(w,"*Clip",d->Obj,d->Id,"data_clip")) return;
  if (putobj(d->Obj,"R",d->Id,&(d->R))==-1) return;
  if (putobj(d->Obj,"G",d->Id,&(d->G))==-1) return;
  if (putobj(d->Obj,"B",d->Id,&(d->B))==-1) return;
  if (putobj(d->Obj,"R2",d->Id,&(d->R2))==-1) return;
  if (putobj(d->Obj,"G2",d->Id,&(d->G2))==-1) return;
  if (putobj(d->Obj,"B2",d->Id,&(d->B2))==-1) return;
  d->ret=ret;
}

void FileDefDialog(struct FileDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=FileDefDialogSetup;
  data->CloseWindow=FileDefDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void CmFileHistory(Widget w,XtPointer client_data,XtPointer call_data)
{
  int i,fil,num;
  char **data;
  struct narray *datafilelist;
  int ret;
  char *name;
  int len,id;
  struct objlist *obj;

  if (menulock || globallock) return;
  for (i=0;i<10;i++) if (w==NgraphApp.fhistory[i]) break;
  fil=i;
  datafilelist=menulocal.datafilelist;
  num=arraynum(datafilelist);
  data=(char **)arraydata(datafilelist);
  if ((fil<0) || (fil>=num) || (data[fil]==NULL)) return;
  if ((obj=chkobject("file"))==NULL) return;
  if ((id=newobj(obj))>=0) {
    len=strlen(data[fil]);
    if ((name=(char *)memalloc(len+1))!=NULL) {
      strcpy(name,data[fil]);
      putobj(obj,"file",id,name);
      FileDialog(&DlgFile,obj,id);
      ret=DialogExecute(TopLevel,&DlgFile);
      if ((ret==IDDELETE) || (ret==IDCANCEL)) {
        FitDel(obj,id);
        delobj(obj,id);
      } else {
        NgraphApp.Changed=TRUE;
      }
    }
  }
  AddDataFileList(data[fil]);
  FileWinUpdate(TRUE);
}

void CmFileNew()
{
  char *name;
  int id,ret;
  struct objlist *obj;
  char *file;

  if (menulock || globallock) return;
  if ((obj=chkobject("file"))==NULL) return;
  if (nGetOpenFileName(TopLevel,"Data new",NULL,NULL,NULL,
      &file,"*",FALSE,menulocal.changedirectory)==IDOK) {
    if ((id=newobj(obj))>=0) {
      if ((name=(char *)memalloc(strlen(file)+1))==NULL) return;
      strcpy(name,file);
      changefilename(name);
      AddDataFileList(name);
      putobj(obj,"file",id,name);
      FileDialog(&DlgFile,obj,id);
      ret=DialogExecute(TopLevel,&DlgFile);
      if ((ret==IDDELETE) || (ret==IDCANCEL)) {
        FitDel(obj,id);
        delobj(obj,id);
      } else NgraphApp.Changed=TRUE;
      FileWinUpdate(TRUE);
    }
  }
  free(file);
}


void CmFileOpen()
{
  char *s,*name;
  int len,id;
  int id0,ids,ide,j,perm,type,ret;
  char *field;
  struct objlist *obj;
  char *file;

  if (menulock || globallock) return;
  if ((obj=chkobject("file"))==NULL) return;
  ids=-1;
  ret=nGetOpenFileNameMulti(TopLevel,"Data open",NULL,
                            &(menulocal.fileopendir),NULL,
                            &file,"*",menulocal.changedirectory);
  if (ret==IDOK) {
    s=file;
    while ((name=getitok2(&s,&len," "))!=NULL) {
      if ((id=newobj(obj))>=0) {
        if (ids==-1) ids=id;
        changefilename(name);
        AddDataFileList(name);
        putobj(obj,"file",id,name);
      }
    }
  }
  free(file);
  FileWinUpdate(TRUE);
  if (ids!=-1) {
    ide=chkobjlastinst(obj);
    id0=-1;
    id=ids;
    while (id<=ide) {
      if (id0!=-1) {
        for (j=0;j<chkobjfieldnum(obj);j++) {
          field=chkobjfieldname(obj,j);
          perm=chkobjperm(obj,field);
          type=chkobjfieldtype(obj,field);
          if ((strcmp2(field,"name")!=0) && (strcmp2(field,"file")!=0)
          && (strcmp2(field,"fit")!=0)
          && ((perm&NREAD)!=0) && ((perm&NWRITE)!=0) && (type<NVFUNC))
            copyobj(obj,field,id,id0);
        }
        FitCopy(obj,id,id0);
        id++;
      } else {
        FileDialog(&DlgFile,obj,id);
        ret=DialogExecute(TopLevel,&DlgFile);
        if ((ret==IDDELETE) || (ret==IDCANCEL)) {
          FitDel(obj,id);
          delobj(obj,id);
          ide--;
        } else if (ret==IDFAPPLY) {
          id0=id;
          id++;
          NgraphApp.Changed=TRUE;
        } else {
          id++;
          NgraphApp.Changed=TRUE;
        }
      }
      FileWinUpdate(TRUE);
    }
  }
}

void CmFileClose()
{
  struct narray farray;
  struct objlist *obj;
  int i;
  int *array,num;

  if (menulock || globallock) return;
  if ((obj=chkobject("file"))==NULL) return;
  if (chkobjlastinst(obj)==-1) return;
  SelectDialog(&DlgSelect,obj,FileCB,(struct narray *)&farray,NULL);
  if (DialogExecute(TopLevel,&DlgSelect)==IDOK) {
    num=arraynum(&farray);
    array=(int *)arraydata(&farray);
    for (i=num-1;i>=0;i--) {
      FitDel(obj,array[i]);
      delobj(obj,array[i]);
      NgraphApp.Changed=TRUE;
    }
    FileWinUpdate(TRUE);
  }
  arraydel(&farray);
}

void CmFileUpdate()
{
  struct objlist *obj;
  int i,j;
  int *array,num;
  int id0,perm,type,ret;
  char *field;
  struct narray farray;
  int last;

  if (menulock || globallock) return;
  if ((obj=chkobject("file"))==NULL) return;
  last=chkobjlastinst(obj);
  if (last==-1) return;
  else if (last==0) {
    arrayinit(&farray,sizeof(int));
    arrayadd(&farray,&last);
    ret=IDOK;
  } else {
    SelectDialog(&DlgSelect,obj,FileCB,(struct narray *)&farray,NULL);
    ret=DialogExecute(TopLevel,&DlgSelect);
  }
  if (ret==IDOK) {
    num=arraynum(&farray);
    array=(int *)arraydata(&farray);
    id0=-1;
    for (i=0;i<num;i++) {
      if (id0!=-1) {
        for (j=0;j<chkobjfieldnum(obj);j++) {
          field=chkobjfieldname(obj,j);
          perm=chkobjperm(obj,field);
          type=chkobjfieldtype(obj,field);
          if ((strcmp2(field,"name")!=0) && (strcmp2(field,"file")!=0)
          && (strcmp2(field,"fit")!=0)
                  && ((perm&NREAD)!=0) && ((perm&NWRITE)!=0) && (type<NVFUNC))
                        copyobj(obj,field,array[i],array[id0]);
        }
        FitCopy(obj,array[i],array[id0]);
      } else {
        FileDialog(&DlgFile,obj,array[i]);
        ret=DialogExecute(TopLevel,&DlgFile);
        if (ret==IDDELETE) {
          FitDel(obj,array[i]);
          delobj(obj,array[i]);
          for (j=i+1;j<num;j++) array[j]--;
        } else if (ret==IDFAPPLY) id0=i;
        if (ret!=IDCANCEL) NgraphApp.Changed=TRUE;
      }
    }
    FileWinUpdate(TRUE);
  }
  arraydel(&farray);
}

void CmFileEdit()
{
  struct objlist *obj;
  int i;
  char *name;
  char *argv[3];
  pid_t pid;
  int last;

  if (menulock || globallock) return;
  if (menulocal.editor==NULL) return;
  if ((obj=chkobject("file"))==NULL) return;
  last=chkobjlastinst(obj);
  if (last==-1) return;
  else if (last==0) i=0;
  else {
    CopyDialog(&DlgCopy,obj,-1,FileCB);
    if (DialogExecute(TopLevel,&DlgCopy)==IDOK) i=DlgCopy.sel;
    else return;
  }
  if (i<0) return;
  argv[0]=menulocal.editor;
  argv[2]=NULL;
  if (getobj(obj,"file",i,0,NULL,&name)==-1) return;
  if (name!=NULL) {
    argv[1]=name;
    if ((pid=fork())>=0) {
      if (pid==0) {
        execvp(argv[0],argv);
        exit(1);
      } else arrayadd(&childlist,&pid);
    }
  }
}

void CmFileOpenB(Widget w,XtPointer client_data,XtPointer call_data)
{
  CmFileOpen();
}

void CmFileMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    CmFileNew();
    break;
  case 1: 
    CmFileOpen();
    break;
  case 2: 
    CmFileUpdate();
    break;
  case 3: 
    CmFileClose();
    break;
  case 4: 
    CmFileEdit();
    break;
  }
}

void CmOptionFileDef()
{
  struct objlist *obj;
  int id;

  if (menulock || globallock) return;
  if ((obj=chkobject("file"))==NULL) return;
  if ((id=newobj(obj))>=0) {
    FileDefDialog(&DlgFileDef,obj,id);
    if (DialogExecute(TopLevel,&DlgFileDef)==IDOK) {
      if (CheckIniFile()) {
        exeobj(obj,"save_config",id,0,NULL);
      }
    }
    delobj(obj,id);
    UpdateAll2();
  }
}

void FileWinFileOpen()
{
  if (menulock || globallock) return;
  CmFileOpen();
}

void FileWinFileEdit()
{
  int sel;
  char *argv[3],*name;
  pid_t pid;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (menulock || globallock) return;
  if (menulocal.editor==NULL) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->filenum)) {
    argv[0]=menulocal.editor;
    argv[2]=NULL;
    if (getobj(d->obj,"file",sel,0,NULL,&name)==-1) return;
    if (name!=NULL) {
      argv[1]=name;
      if ((pid=fork())>=0) {
        if (pid==0) {
          execvp(argv[0],argv);
          exit(1);
        } else arrayadd(&childlist,&pid);
      }
    }
  }
}

void FileWinFileDelete()
{
  int sel;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->filenum)) {
    FitDel(d->obj,sel);
    delobj(d->obj,sel);
    FileWinUpdate(FALSE);
    NgraphApp.Changed=TRUE;
  }
}

void FileWinFileCopy()
{
  int sel;
  int j,id,perm,type;
  char *field;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->filenum)) {
    if ((id=newobj(d->obj))>=0) {
      for (j=0;j<chkobjfieldnum(d->obj);j++) {
        field=chkobjfieldname(d->obj,j);
        perm=chkobjperm(d->obj,field);
        type=chkobjfieldtype(d->obj,field);
        if ((strcmp2(field,"name")!=0) && (strcmp2(field,"fit")!=0)
          && ((perm&NREAD)!=0) && ((perm&NWRITE)!=0) && (type<NVFUNC))
          copyobj(d->obj,field,id,sel);
      }
      FitCopy(d->obj,id,sel);
      d->filenum++;
      NgraphApp.Changed=TRUE;
    }
    d->select=sel;
    FileWinUpdate(FALSE);
  }
}

void FileWinFileCopy2()
{
  int sel;
  int j,id,perm,type;
  char *field;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->filenum)) {
    if ((id=newobj(d->obj))>=0) {
      for (j=0;j<chkobjfieldnum(d->obj);j++) {
        field=chkobjfieldname(d->obj,j);
        perm=chkobjperm(d->obj,field);
        type=chkobjfieldtype(d->obj,field);
        if ((strcmp2(field,"name")!=0) && (strcmp2(field,"fit")!=0)
          && ((perm&NREAD)!=0) && ((perm&NWRITE)!=0) && (type<NVFUNC))
          copyobj(d->obj,field,id,sel);
      }
      FitCopy(d->obj,id,sel);
      d->filenum++;
      for (j=d->filenum;j>sel+1;j--) moveupobj(d->obj,j);
      NgraphApp.Changed=TRUE;
    }
    d->select=sel;
    FileWinUpdate(FALSE);
  }
}

void FileWinFileTop()
{
  int sel;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->filenum)) {
    movetopobj(d->obj,sel);
    d->select=0;
    FileWinUpdate(FALSE);
    NgraphApp.Changed=TRUE;
  }
}

void FileWinFileLast()
{
  int sel;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->filenum)) {
    movelastobj(d->obj,sel);
    d->select=d->filenum;
    FileWinUpdate(FALSE);
    NgraphApp.Changed=TRUE;
  }
}

void FileWinFileUp()
{
  int sel;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=1) && (sel<=d->filenum)) {
    moveupobj(d->obj,sel);
    d->select=sel-1;
    FileWinUpdate(FALSE);
    NgraphApp.Changed=TRUE;
  }
}

void FileWinFileDown()
{
  int sel;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->filenum-1)) {
    movedownobj(d->obj,sel);
    d->select=sel+1;
    FileWinUpdate(FALSE);
    NgraphApp.Changed=TRUE;
  }
}

void FileWinFileUpdate()
{
  int sel,ret;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->filenum)) {
    FileDialog(&DlgFile,d->obj,sel);
    if ((ret=DialogExecute(TopLevel,&DlgFile))==IDDELETE) {
      FitDel(d->obj,sel);
      delobj(d->obj,sel);
      d->select=-1;
    }
    if (ret!=IDCANCEL) NgraphApp.Changed=TRUE;
    FileWinUpdate(FALSE);
  }
}

void FileWinFileDraw()
{
  int i,sel;
  int hidden;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->filenum)) {
    for (i=0;i<=d->filenum;i++) {
      if (i==sel) hidden=FALSE;
      else hidden=TRUE;
      putobj(d->obj,"hidden",i,&hidden);
    }
  } else {
    hidden=FALSE;
    for (i=0;i<=d->filenum;i++) putobj(d->obj,"hidden",i,&hidden);
  }
  CmViewerDrawB(NULL,NULL,NULL);
  FileWinUpdate(FALSE);
}

void FileWinFileHidden()
{
  int sel;
  int hidden;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->filenum)) {
    getobj(d->obj,"hidden",sel,0,NULL,&hidden);
    hidden=hidden?FALSE:TRUE;
    putobj(d->obj,"hidden",sel,&hidden);
    FileWinUpdate(FALSE);
    NgraphApp.Changed=TRUE;
  }
}

void FileWinChangeFileNum()
{
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (d->text==NULL) return;
  XtVaSetValues(d->text,XmNheight,(d->filenum+3)*FHeight,NULL);
}

void FileWinUpdate(int clear)
{
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  d->filenum=chkobjlastinst(d->obj);
  FileWinChangeFileNum();
  if (d->text==NULL) return;
  XClearArea(XtDisplay(d->text),XtWindow(d->text),0,0,0,0,TRUE);
}

void FileWinFit()
{
  struct FileWin *d;
  struct objlist *fitobj,*obj2;
  char *fit;
  int sel,idnum,fitid=0,ret;
  struct narray iarray;

  d=&(NgraphApp.FileWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((fitobj=chkobject("fit"))==NULL) return;
  if (getobj(d->obj,"fit",sel,0,NULL,&fit)==-1) return;
  if (fit!=NULL) {
    arrayinit(&iarray,sizeof(int));
    if (getobjilist(fit,&obj2,&iarray,FALSE,NULL)) {
      arraydel(&iarray);
      return;
    }
    idnum=arraynum(&iarray);
    if ((obj2!=fitobj) || (idnum<1)) {
      if (putobj(d->obj,"fit",sel,NULL)==-1) {
        arraydel(&iarray);
        return;
      }
    } else fitid=*(int *)arraylast(&iarray);
    arraydel(&iarray);
  }
  if (fit==NULL) return;
  FitDialog(&DlgFit,fitobj,fitid);
  ret=DialogExecute(TopLevel,&DlgFit);
  if (ret==IDDELETE) {
    delobj(fitobj,fitid);
    putobj(d->obj,"fit",sel,NULL);
  }
}

void FileWinExpose(Widget wi,XtPointer client_data,XtPointer call_data)
{
  XmDrawingAreaCallbackStruct *dd;
  XExposeEvent *e;
  Display *disp;
  Window win;
  GC gc;
  int GGC;
  int h,w,x,y,i,j,k,hidden,dpi;
  char buf[256],*valstr;
  char *file,*bfile;
  XRectangle rect;
  int len;
  int cx,cy,type,marktype,fr,fg,fb,fr2,fg2,fb2,intp,spcond,spnum;
  int poly[14];
  double spx[7],spy[7],spz[7];
  double spc[6][7],spc2[6];
  struct mxlocal mxsave;
  struct narray *mask,*move;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (d->text==NULL) return;
  dd=(XmDrawingAreaCallbackStruct *)call_data;
  e=(XExposeEvent *)(dd->event);
  disp=e->display;
  win=e->window;
  gc=XCreateGC(disp,win,0,0);
  if (globallock) return;
  d->filenum=chkobjlastinst(d->obj);
  h=FHeight;
  w=FWidth;  
  XSetForeground(disp,gc,gray);
  XFillRectangle(disp,win,gc,0,0,80*w+h+2*w,h);
  x=FWidth;
  y=FAscent;
  XSetForeground(disp,gc,black);
  rect.y=y-FAscent;
  rect.height=h;
  rect.x=x;
  rect.width=6*w;
  len=sprintf(buf,"#");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=6*w;
  rect.x=x;
  rect.width=12*w;
  len=sprintf(buf,"file        ");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=13*w;
  rect.x=x;
  rect.width=3*w;
  len=sprintf(buf,"  x");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=3*w;
  rect.x=x;
  rect.width=3*w;
  len=sprintf(buf,"  y");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=3*w;
  rect.x=x;
  rect.width=3*w;
  len=sprintf(buf," ax");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=3*w;
  rect.x=x;
  rect.width=3*w;
  len=sprintf(buf," ay");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=3*w;
  rect.x=x;
  rect.width=3*w+h;
  len=sprintf(buf," tp");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=3*w+h;
  rect.x=x;
  rect.width=6*w;
  len=sprintf(buf,"  size");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=6*w;
  rect.x=x;
  rect.width=6*w;
  len=sprintf(buf," width");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=6*w;
  rect.x=x;
  rect.width=6*w;
  len=sprintf(buf,"  skip");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=6*w;
  rect.x=x;
  rect.width=6*w;
  len=sprintf(buf,"  step");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=6*w;
  rect.x=x;
  rect.width=6*w;
  len=sprintf(buf," final");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=6*w;
  rect.x=x;
  rect.width=6*w;
  len=sprintf(buf,"   num");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=6*w;
  rect.x=x+w;
  rect.width=7*w;
  len=sprintf(buf,"^#");
  ExtTextOut(disp,win,gc,x+w,y,&rect,buf,len);

  for (i=0;i<=d->filenum;i++) {
      x=w;
      y=(i+1)*h+FAscent;
      rect.y=y-FAscent;
      rect.height=h;

      getobj(d->obj,"hidden",i,0,NULL,&hidden);
      if (hidden) XSetForeground(disp,gc,gray);
      else {
        getobj(d->obj,"mask",i,0,NULL,&mask);
        getobj(d->obj,"move_data",i,0,NULL,&move);
        if ((arraynum(mask)!=0) || (arraynum(move)!=0))
          XSetForeground(disp,gc,blue);
        else XSetForeground(disp,gc,black);
      }
      if (i==d->select) {
        XSetForeground(disp,gc,black);
        XFillRectangle(disp,win,gc,0,rect.y,80*w+h+w,rect.height);
        XSetForeground(disp,gc,white);
      }

      getobj(d->obj,"id",i,0,NULL,&cx);
      rect.x=x;
      rect.width=6*w;
      len=sprintf(buf,"%d",cx);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=6*w;

      getobj(d->obj,"file",i,0,NULL,&file);
      bfile=getbasename(file);
      rect.x=x;
      rect.width=12*w;
      if (bfile!=NULL) {
        ExtTextOut(disp,win,gc,x,y,&rect,bfile,strlen(bfile));
        memfree(bfile);
      } else
        ExtTextOut(disp,win,gc,x,y,&rect,"....................",20);
      x+=13*w;

      getobj(d->obj,"x",i,0,NULL,&cx);
      rect.x=x;
      rect.width=3*w;
      len=sprintf(buf,"%3d",cx);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=3*w;

      getobj(d->obj,"y",i,0,NULL,&cy);
      rect.x=x;
      rect.width=3*w;
      len=sprintf(buf,"%3d",cy);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=3*w;

      sgetobjfield(d->obj,i,"axis_x",NULL,&valstr,FALSE,FALSE,FALSE);
      for (j=0;(valstr[j]!='\0') && (valstr[j]!=':');j++);
      if (valstr[j]==':') j++;
      rect.x=x;
      rect.width=3*w;
      len=sprintf(buf,"%3s",valstr+j);
      memfree(valstr);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=3*w;

      sgetobjfield(d->obj,i,"axis_y",NULL,&valstr,FALSE,FALSE,FALSE);
      for (j=0;(valstr[j]!='\0') && (valstr[j]!=':');j++);
      if (valstr[j]==':') j++;
      rect.x=x;
      rect.width=3*w;
      len=sprintf(buf,"%3s",valstr+j);
      memfree(valstr);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=3*w;

      x+=w;
      getobj(d->obj,"type",i,0,NULL,&type);
      getobj(d->obj,"R",i,0,NULL,&fr);
      getobj(d->obj,"G",i,0,NULL,&fg);
      getobj(d->obj,"B",i,0,NULL,&fb);
      getobj(d->obj,"R2",i,0,NULL,&fr2);
      getobj(d->obj,"G2",i,0,NULL,&fg2);
      getobj(d->obj,"B2",i,0,NULL,&fb2);
      dpi=nround(h*254.0);
      mxsaveGC(gc,win,0,0,&mxsave,dpi,NULL);
      GGC=_GRAopen(chkobjectname(menulocal.obj),"_output",menulocal.outputobj,
                  menulocal.inst,menulocal.output,-1,-1,-1,NULL,
                  mxlocal);
      if (GGC>=0) {
        GRAview(GGC,x*10/h,(y+FDescent)*10/h-10,x*10/h+10,(y+FDescent)*10/h,0);
        switch (type) {
        case 0:
          getobj(d->obj,"mark_type",i,0,NULL,&marktype);
          GRAlinestyle(GGC,0,NULL,1,0,0,1000);
          GRAmark(GGC,marktype,5,5,8,fr,fg,fb,fr2,fg2,fb2);
          break;
        case 1:
          GRAcolor(GGC,fr,fg,fb);
          GRAlinestyle(GGC,0,NULL,1,0,0,1000);
          GRAline(GGC,0,5,10,5);
          break;
        case 2:
          poly[0]=0;  poly[1]=5; poly[2]=3; poly[3]=2; poly[4]=7; poly[5]=8;
          poly[6]=10;poly[7]=5; poly[8]=7; poly[9]=2; poly[10]=3;poly[11]=8;
          poly[12]=0; poly[13]=5;
          GRAcolor(GGC,fr,fg,fb);
          GRAlinestyle(GGC,0,NULL,1,0,0,1000);
          GRAdrawpoly(GGC,7,poly,0);
          break;
        case 3:
          spx[0]=0; spx[1]=3; spx[2]=7; spx[3]=10;spx[4]=7; spx[5]=3; spx[6]=0;
          spy[0]=5;spy[1]=2; spy[2]=8; spy[3]=5; spy[4]=2; spy[5]=8; spy[6]=5;
          for (j=0;j<7;j++) spz[j]=j;
          getobj(d->obj,"interpolation",i,0,NULL,&intp);
          if ((intp==0) || (intp==2)) {
            spcond=SPLCND2NDDIF;
            spnum=4;
          } else {
            spcond=SPLCNDPERIODIC;
            spnum=7;
          }
          spline(spz,spx,spc[0],spc[1],spc[2],spnum,spcond,spcond,0,0);
          spline(spz,spy,spc[3],spc[4],spc[5],spnum,spcond,spcond,0,0);
          GRAcolor(GGC,fr,fg,fb);
          GRAcurvefirst(GGC,0,NULL,NULL,NULL,
                        splinedif,splineint,NULL,spx[0],spy[0]);
          for (j=0;j<spnum-1;j++) {
            for (k=0;k<6;k++) spc2[k]=spc[k][j];
            if (!GRAcurve(GGC,spc2,spx[j],spy[j])) break;
          }
          break;
        case 4: case 5: case 6: case 7: case 8:
          GRAcolor(GGC,fr,fg,fb);
          if ((type==4) || (type==5)) GRAlinestyle(GGC,0,NULL,1,0,0,1000);
          else GRAlinestyle(GGC,0,NULL,1,2,0,1000);
          spx[0]=0;
          spy[0]=7;
          spx[1]=10;
          spy[1]=3;
          if ((type==4) || (type==5)) GRAline(GGC,spx[0],spy[0],spx[1],spy[1]);
          if (type==5) {
            poly[0]=9;  poly[1]=3;
            poly[2]=spx[1]; poly[3]=spy[1];
            poly[4]=10; poly[5]=4;
            GRAdrawpoly(GGC,3,poly,0);
          }
          if ((type==7) || (type==8)) {
            if (type==7) GRAcolor(GGC,fr2,fg2,fb2);
            GRArectangle(GGC,spx[0],spy[0],spx[1],spy[1],1);
            if (type==7) GRAcolor(GGC,fr,fg,fb);
          }
          if ((type==6) || (type==7)) {
            GRAline(GGC,spx[0],spy[0],spx[0],spy[1]);
            GRAline(GGC,spx[0],spy[1],spx[1],spy[1]);
            GRAline(GGC,spx[1],spy[1],spx[1],spy[0]);
            GRAline(GGC,spx[1],spy[0],spx[0],spy[0]);
          }
          break;
        case 9: case 10:
          GRAcolor(GGC,fr,fg,fb);
          GRAlinestyle(GGC,0,NULL,1,0,0,1000);
          if (type==9) {
            GRAline(GGC,0,5,10,5);
            GRAline(GGC,0,3,0,7);
            GRAline(GGC,10,3,10,7);
          } else {
            GRAline(GGC,5,1,5,9);
            GRAline(GGC,3,1,7,1);
            GRAline(GGC,3,9,7,9);
          }
          break;
        case 11: case 12:
          GRAcolor(GGC,fr,fg,fb);
          GRAlinestyle(GGC,0,NULL,1,0,0,1000);
          if (type==11) {
            GRAmoveto(GGC,0,9);
            GRAlineto(GGC,3,9);
            GRAlineto(GGC,3,5);
            GRAlineto(GGC,7,5);
            GRAlineto(GGC,7,1);
            GRAlineto(GGC,10,1);
          } else {
            GRAmoveto(GGC,0,9);
            GRAlineto(GGC,0,6);
            GRAlineto(GGC,5,6);
            GRAlineto(GGC,5,3);
            GRAlineto(GGC,10,3);
            GRAlineto(GGC,10,1);
          }
          break;
        case 13: case 14: case 15: case 16: case 17: case 18:
          GRAcolor(GGC,fr,fg,fb);
          GRAlinestyle(GGC,0,NULL,1,2,0,1000);
          if ((type==15) || (type==17)) {
            if (type==15) GRAcolor(GGC,fr2,fg2,fb2);
            GRArectangle(GGC,0,4,10,6,1);
            if (type==15) GRAcolor(GGC,fr,fg,fb);
          }
          if ((type==16) || (type==18)) {
            if (type==16) GRAcolor(GGC,fr2,fg2,fb2);
            GRArectangle(GGC,4,1,6,9,1);
            if (type==16) GRAcolor(GGC,fr,fg,fb);
          }
          if ((type==13) || (type==15)) {
            GRAline(GGC,0,4,10,4);
            GRAline(GGC,10,4,10,6);
            GRAline(GGC,10,6,0,6);
            GRAline(GGC,0,6,0,4);
          }
          if ((type==14) || (type==16)) {
            GRAline(GGC,4,1,6,1);
            GRAline(GGC,6,1,6,9);
            GRAline(GGC,6,9,4,9);
            GRAline(GGC,4,9,4,1);
          }
          break;
        }
      }
      _GRAclose(GGC);
      mxrestoreGC(&mxsave);

      if (hidden) XSetForeground(disp,gc,gray);
      else {
        if ((arraynum(mask)!=0) || (arraynum(move)!=0))
          XSetForeground(disp,gc,blue);
        else XSetForeground(disp,gc,black);
      }
      if (i==d->select) {
        XSetForeground(disp,gc,white);
      }


      if ((type==3) && (intp>=2)) {
        rect.x=x+h;
        rect.width=h+2*w;
        len=sprintf(buf,"B");
        ExtTextOut(disp,win,gc,x+h,y,&rect,buf,len);
      } else if (type==19) {
        rect.x=x;
        rect.width=h+2*w;
        len=sprintf(buf,"FIT");
        ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      }
      x+=h+2*w;

      getobj(d->obj,"mark_size",i,0,NULL,&cx);
      rect.x=x;
      rect.width=6*w;
      len=sprintf(buf,"%6d",cx);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=6*w;

      getobj(d->obj,"line_width",i,0,NULL,&cx);
      rect.x=x;
      rect.width=6*w;
      len=sprintf(buf,"%6d",cx);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=6*w;

      getobj(d->obj,"head_skip",i,0,NULL,&cx);
      rect.x=x;
      rect.width=6*w;
      len=sprintf(buf,"%6d",cx);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=6*w;

      getobj(d->obj,"read_step",i,0,NULL,&cx);
      rect.x=x;
      rect.width=6*w;
      len=sprintf(buf,"%6d",cx);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=6*w;

      getobj(d->obj,"final_line",i,0,NULL,&cx);
      rect.x=x;
      rect.width=6*w;
      len=sprintf(buf,"%6d",cx);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=6*w;

      getobj(d->obj,"data_num",i,0,NULL,&cx);
      rect.x=x;
      rect.width=6*w;
      len=sprintf(buf,"%6d",cx);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=6*w;

      getobj(d->obj,"oid",i,0,NULL,&cx);
      rect.x=x+w;
      rect.width=7*w;
      len=sprintf(buf,"^%d",cx);
      ExtTextOut(disp,win,gc,x+w,y,&rect,buf,len);
      x+=8*w;
  }
  XFreeGC(disp,gc);
}

void FileWinEvLButtonDown(unsigned int state,TPoint point,struct FileWin *d)
{
  int sel;

  if (menulock || globallock) return;
  sel=point.y/FHeight-1;
  if (sel!=d->select) {
    FileWinUpdate(TRUE);
    d->select=sel;
  }
}

void FileWinEvLButtonDblClk(unsigned int state,TPoint point,struct FileWin *d)
{
  if (menulock || globallock) return;
  FileWinFileUpdate();
}

void FileWinEvRButtonDown(unsigned int state,TPoint point,struct FileWin *d,
                          XButtonPressedEvent *event)
{
  int sel;
  struct objlist *fitobj,*obj2;
  char *fit;
  int idnum;
  struct narray iarray;

  if (menulock || globallock) return;
  sel=point.y/FHeight-1;
  if (sel!=d->select) {
    FileWinUpdate(TRUE);
    d->select=sel;
  }
  sel=d->select;
  if ((sel>=0) && (sel<=d->filenum)) {
    XtSetSensitive(XtNameToWidget(d->popup,"button_0"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_1"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_2"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_3"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_4"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_5"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_6"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_7"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_8"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_9"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_10"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_11"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_12"),False);
    if ((fitobj=chkobject("fit"))!=NULL) {
      if (getobj(d->obj,"fit",sel,0,NULL,&fit)!=-1) {
        if (fit!=NULL) {
          arrayinit(&iarray,sizeof(int));
          if (!getobjilist(fit,&obj2,&iarray,FALSE,NULL)) {
            idnum=arraynum(&iarray);
            if ((obj2==fitobj) && (idnum>0))
              XtSetSensitive(XtNameToWidget(d->popup,"button_12"),True);
          }
          arraydel(&iarray);
        }
      }
    }
  } else {
    XtSetSensitive(XtNameToWidget(d->popup,"button_0"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_1"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_2"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_3"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_4"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_5"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_6"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_7"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_8"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_9"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_10"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_11"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_12"),False);
  }


  XmMenuPosition(d->popup,event);
  XtManageChild(d->popup);
}

Time FileWinTime=0;
TPoint FileWinPoint;

void FileWinEvButtonDown(Widget w,XtPointer client_data,XEvent *event,
                         Boolean *dispatch)
{
  struct FileWin *d;
  XButtonEvent *e;
  TPoint point;
  int dbl;

  d=(struct FileWin *)client_data;
  e=(XButtonEvent *)event;
  point.x=e->x;
  point.y=e->y;
  if (((e->time-FileWinTime)<menulocal.mouseclick)
  && (FileWinPoint.x==point.x) && (FileWinPoint.y==point.y)) dbl=TRUE;
  else dbl=FALSE;
  FileWinTime=e->time;
  FileWinPoint.x=point.x;
  FileWinPoint.y=point.y;
  if (e->button==Button1) {
    if (dbl) FileWinEvLButtonDblClk(e->state,point,d);
    else FileWinEvLButtonDown(e->state,point,d);
  } else if (e->button==Button2) {
    FileWinEvLButtonDown(e->state,point,d);
    FileWinEvLButtonDblClk(e->state,point,d);
  } else if (e->button==Button3) FileWinEvRButtonDown(e->state,point,d,e);
}

void FileWinPopupMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    FileWinFileOpen();
    break;
  case 1:
    FileWinFileUpdate();
    break;
  case 2:
    FileWinFileDelete(); 
    break;
  case 3:
    FileWinFileTop();
    break;
  case 4:
    FileWinFileUp();
    break;
  case 5:
    FileWinFileDown();
    break;
  case 6: 
    FileWinFileLast();
    break;
  case 7: 
    FileWinFileEdit();
    break;
  case 8: 
    FileWinFileCopy();
    break;
  case 9: 
    FileWinFileCopy2();
    break;
  case 10: 
    FileWinFileDraw();
    break;
  case 11: 
    FileWinFileHidden();
    break;
  case 12: 
    FileWinFit();
    break;
  }
}

void FileWinEvKeyDown(Widget w,XtPointer client_data,XEvent *event,
                     Boolean *dispatch)
{
  struct FileWin *d;
  XKeyEvent *e;
  KeySym sym;
  int sel;

  if (menulock || globallock) return;
  d=(struct FileWin *)client_data;
  e=(XKeyEvent *)event;
  sym=XKeycodeToKeysym(e->display,e->keycode,0);
  sel=d->select;
  switch (sym) {
  case XK_Down:
    if (e->state & ShiftMask) FileWinFileDown();
    else {
      if ((sel==-1) && (d->filenum>=0)) sel=0;
      else if (sel<d->filenum) sel++;
      if (sel!=d->select) {
        d->select=sel;
        FileWinUpdate(TRUE);
      }
    }
    break;
  case XK_Up:
    if (e->state & ShiftMask) FileWinFileUp();
    else {
      if ((sel==-1) && (d->filenum>=0)) sel=d->filenum;
      else if (sel>0) sel--;
      if (sel!=d->select) {
        d->select=sel;
        FileWinUpdate(TRUE);
      }
    }
    break;
  case XK_Delete:
    FileWinFileDelete();
    break;
  case XK_Insert:
    if (e->state & ShiftMask) FileWinFileCopy2();
    else FileWinFileCopy();
    break;
  case XK_Home:
    if (e->state & ShiftMask) FileWinFileTop();
    break;
  case XK_End:
    if (e->state & ShiftMask) FileWinFileLast();
    break;
  case XK_Return:
    FileWinFileUpdate();
    break;
  case XK_space:
    FileWinFileDraw();
    break;
  case XK_BackSpace:
    FileWinFileHidden();
    break;
  case XK_f:
  case XK_F:
    if (e->state & ControlMask) FileWinFit();
    break;
  }
}

void FileWindowUnmap(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct FileWin *d;
  Position x,y,x0,y0;
  Dimension w0,h0;

  d=&(NgraphApp.FileWin);
  if (d->Win!=NULL) {
    XtVaGetValues(d->Win,XmNx,&x,XmNy,&y,
                         XmNwidth,&w0,XmNheight,&h0,NULL);
    menulocal.filewidth=w0;
    menulocal.fileheight=h0;
    XtTranslateCoords(TopLevel,0,0,&x0,&y0);
    menulocal.filex=x-x0;
    menulocal.filey=y-y0;
    XtDestroyWidget(d->Win);
    d->Win=NULL;
    d->text=NULL;
    XmToggleButtonSetState(XtNameToWidget(TopLevel,"*windowmenu.button_0"),
                           False,False);
  }
}

void CmFileWinMath(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct objlist *obj;

  if (menulock || globallock) return;
  obj=chkobject("file");
  MathDialog(&DlgMath,obj);
  DialogExecute(TopLevel,&DlgMath);
}

void CmFileWindow(Widget w,XtPointer client_data,XtPointer call_data)
{
  Arg al[20];
  Cardinal ac;
  Widget dlg,scw,clip;
  int width,height;
  Position x,y;
  struct FileWin *d;

  d=&(NgraphApp.FileWin);
  if (d->Win!=NULL) {
    XtUnmanageChild(d->Win);
  } else {
    if (menulocal.filewidth==CW_USEDEFAULT) width=FWidth*80+FHeight+2*FWidth;
    else width=menulocal.filewidth;
    if (menulocal.fileheight==CW_USEDEFAULT) height=FHeight*10;
    else height=menulocal.fileheight;
    ac=0;
    XtSetArg(al[ac],XmNborderWidth,1);ac++;
    XtSetArg(al[ac],XmNdialogStyle,XmDIALOG_MODELESS); ac++;
    XtSetArg(al[ac],XmNautoUnmanage,FALSE); ac++;
    XtSetArg(al[ac],XmNwidth,width); ac++;
    XtSetArg(al[ac],XmNheight,height); ac++;
    if ((menulocal.filex!=CW_USEDEFAULT) && (menulocal.filey!=CW_USEDEFAULT)) {
      XtTranslateCoords(TopLevel,menulocal.filex,menulocal.filey,&x,&y);
      x-=menulocal.framex;
      y-=menulocal.framey;
      if (x<0) x=0;
      if (y<0) y=0;
      XtSetArg(al[ac],XmNdefaultPosition,False); ac++;
      XtSetArg(al[ac],XmNx,x); ac++;
      XtSetArg(al[ac],XmNy,y); ac++;
    } else {
      XtSetArg(al[ac],XmNdefaultPosition,True); ac++;
    }
    XtManageChild(dlg=XmCreateFormDialog(TopLevel,"datawindow",al,ac));
    d->Win=dlg;
    XtAddCallback(dlg,XmNunmapCallback,FileWindowUnmap,NULL);
    ac=0;
    XtSetArg(al[ac],XmNtopAttachment,XmATTACH_FORM); ac++;
    XtSetArg(al[ac],XmNleftAttachment,XmATTACH_FORM); ac++;
    XtSetArg(al[ac],XmNbottomAttachment,XmATTACH_FORM); ac++;
    XtSetArg(al[ac],XmNrightAttachment,XmATTACH_FORM); ac++; 
    XtSetArg(al[ac],XmNalignment,XmALIGNMENT_BEGINNING); ac++;
    XtSetArg(al[ac],XmNscrollingPolicy,XmAUTOMATIC); ac++;
    XtSetArg(al[ac],XmNscrollBarDisplayPolicy,XmSTATIC); ac++;
    XtSetArg(al[ac],XmNwidth,width); ac++;
    XtSetArg(al[ac],XmNheight,height); ac++;
    XtSetArg(al[ac],XmNborderWidth,0);ac++;
    XtManageChild(scw=XmCreateScrolledWindow(dlg,NULL,al,ac));
    ac=0;
    XtSetArg(al[ac],XmNwidth,FWidth*80+FHeight+2*FWidth); ac++; 
    XtSetArg(al[ac],XmNheight,height); ac++;
    XtSetArg(al[ac],XmNbackground,WhitePixel(XtDisplay(TopLevel),0)); ac++;
    XtManageChild(d->text=XmCreateDrawingArea(scw,NULL,al,ac));
    XtVaGetValues(scw,XmNclipWindow,&clip,NULL); 
    XtVaSetValues(clip,XmNbackground,WhitePixel(XtDisplay(TopLevel),0),NULL);
    XtAddCallback(d->text,XmNexposeCallback,FileWinExpose,NULL); 
    XtAddEventHandler(d->text,ButtonPressMask,False,FileWinEvButtonDown,d);
    d->obj=chkobject("file");
    d->filenum=chkobjlastinst(d->obj);
    d->select=-1;
    FileWinChangeFileNum();
    d->popup=XmVaCreateSimplePopupMenu(d->text,"datapopup",FileWinPopupMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);
    XtAddEventHandler(d->text,KeyPressMask,False,FileWinEvKeyDown,d);
    XmToggleButtonSetState(XtNameToWidget(TopLevel,"*windowmenu.button_0"),
                           True,False);
  }
}
