"Fossies" - the Fresh Open Source Software archive

Member "imal-3.7.5a/xmtnimage49.cc" of archive imal-source.tar.gz:


//--------------------------------------------------------------------------//
// xmtnimage49.cc                                                           //
// filename callbacks                                                       //
// Latest revision: 08-04-2008                                              //
// Copyright (C) 2000 by Thomas J. Nelson                                   //
// See xmtnimage.h for Copyright Notice                                     //
//--------------------------------------------------------------------------//

#include "xmtnimage.h"

extern Globals     g;
extern Image      *z;
extern int         ci;
char lestif_filename[FILENAMELENGTH] = "nothing";
int toppos=1;
int in_fscancelcb = 0;


//--------------------------------------------------------------------//
// filenamecb                                                         //
// Calling routine must maintain a dynamic list of Widgets, then      //
//   destroy them when finished.                                      //
//--------------------------------------------------------------------//
void filenamecb(Widget widget, XtP client_data, XmACB *call_data)
{
   call_data=call_data;  // Keep compiler quiet
   Widget f,w,w3,dirmaskwidget,bb;

   XmString title, dir_mask, pathxms=NULL;
   int n, itemcount;
   Arg args[100];
   clickboxinfo *c = (clickboxinfo *)client_data;
   int wc = c->wc;
   Widget flist;

   int rx,ry,wx,wy; 
   uint keys;
   Window rwin, cwin; 

   ////  Find current position of main window & image number
   XQueryPointer(g.display,g.main_window,&rwin,&cwin,&rx,&ry,&wx,&wy,&keys);
   g.main_xpos = rx-wx;
   g.main_ypos = ry-wy;

   n = 0;
   XtSetArg(args[n], XmNdialogStyle, XmDIALOG_MODELESS); n++;
   XtSetArg(args[n], XmNdefaultPosition, False); n++;
   XtSetArg(args[n], XmNx, min(g.xres-380, g.main_xpos + 50)); n++;
   XtSetArg(args[n], XmNy, g.main_ypos - 50); n++;
   XtSetArg(args[n], XmNtitle, "File Selection"); n++;
   ////  Stop Motif from trying to grab another color if none are available.
   if(g.want_colormaps)  
   {    XtSetArg(args[n], XmNbackground, g.main_bcolor); n++;
        XtSetArg(args[n], XmNforeground, g.main_fcolor); n++;
   }
   w = bb = c->w[wc++] = XmCreateBulletinBoardDialog(widget,(char*)"Select File",args,n);
   c->form = bb;
   title = XmStringLtoRCreate((char*)"Filter",XmSTRING_DEFAULT_CHARSET);   
   if(c->dirmask)
        dir_mask = XmStringLtoRCreate(c->dirmask,XmSTRING_DEFAULT_CHARSET); 
   else
        dir_mask = XmStringLtoRCreate((char*)"*",XmSTRING_DEFAULT_CHARSET); 

   n = 0;
   XtSetArg(args[n], XmNhighlightThickness, 1); n++;  
   XtSetArg(args[n], XmNdirMask, dir_mask); n++;  
   XtSetArg(args[n], XmNresizable, True); n++;  
   XtSetArg(args[n], XmNfilterLabelString, title); n++; 
   if(c->path != NULL)
   {   XtSetArg(args[n], XmNdirectory, pathxms = XmStringLtoRCreate(c->path,XmSTRING_DEFAULT_CHARSET)); n++;
   }
   ////  Stop Motif from trying to grab another color if none are available.
   if(g.want_colormaps)  
   {    XtSetArg(args[n], XmNbackground, g.main_bcolor); n++;
        XtSetArg(args[n], XmNforeground, g.main_fcolor); n++;
   }
   f = c->w[wc++] = XmCreateFileSelectionBox(w, (char*)"FileSelector", args, n);

   Widget child;
   child = c->listwidget = XmFileSelectionBoxGetChild(f, XmDIALOG_LIST);
   if(c->type==MULTIPLE)
       XtVaSetValues(child, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL);
    
   XtVaGetValues(child, XmNitemCount, &itemcount, NULL);
   toppos = min(toppos, itemcount);
  
   XtVaSetValues(child, XmNtopItemPosition, toppos, NULL);

   ////   The first pushbutton is automatically placed in the wrong
   ////   position, so an unused, unmanaged pushbutton must be added
   ////   to trick Motif.
   
   n = 0;
   ////  Stop Motif from trying to grab another color if none are available.
   if(g.want_colormaps)  
   {    XtSetArg(args[n], XmNbackground, g.main_bcolor); n++;
        XtSetArg(args[n], XmNforeground, g.main_fcolor); n++;
   }
   c->w[wc++] = XmCreatePushButton(f, (char*)"crudola", args, n);

   n = 0;
   XtSetArg(args[n], XmNchildPlacement, XmPLACE_BELOW_SELECTION); n++;
   ////  Stop Motif from trying to grab another color if none are available.
   if(g.want_colormaps)  
   {    XtSetArg(args[n], XmNbackground, g.main_bcolor); n++;
        XtSetArg(args[n], XmNforeground, g.main_fcolor); n++;
   }
   w3 = c->w[wc++] = XmCreatePushButton(f, (char*)"Chdir", args, n);
   XtManageChild(w3);

   ////  Set c->widget[0] to the fileselectionbox widget.
   ////  c->widget[1] is the 'filename' push button in dialog box.

   c->widget[0] = w; 
   XtAddCallback(f, XmNcancelCallback, (XtCBP)fscancelcb, (XtP)c);
   XtAddCallback(f, XmNokCallback, (XtCBP)fsokcb, (XtP)c); 
   XtAddCallback(bb, XmNunmapCallback, (XtCBP)fsunmapcb, (XtP)c);

   flist =  XmFileSelectionBoxGetChild(f, XmDIALOG_LIST);
   XtAddCallback(flist, XmNsingleSelectionCallback, (XtCBP)fsscb, (XtP)flist);
   XtAddCallback(flist, XmNmultipleSelectionCallback, (XtCBP)fsscb, (XtP)flist);

   XtAddCallback(w3, XmNactivateCallback, (XtCBP)fscdcb, (XtP)f);
   dirmaskwidget = XmFileSelectionBoxGetChild(f, XmDIALOG_FILTER_TEXT);
   XtAddCallback(dirmaskwidget, XmNvalueChangedCallback, (XtCBP)fsdirmaskcb, (XtP)c); 

   if(c->path != NULL) XmStringFree(pathxms);
   XmStringFree(title);
   XmStringFree(dir_mask);
   XtManageChild(f);
   XtManageChild(w);

   //// It is necessary to manually set the colors in each subwindow.
           
   w = XmFileSelectionBoxGetChild(f, XmDIALOG_LIST);
   XtVaSetValues(w, 
#ifdef SOLARIS 
            XmNwidth, 400,
#endif
            XmNscrollBarDisplayPolicy, XmSTATIC,  // Essential for Solaris
            NULL);

   ////  Stop Motif from trying to grab another color if none are available.
   if(g.want_colormaps)  
   {   
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_APPLY_BUTTON);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_CANCEL_BUTTON);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_DEFAULT_BUTTON);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_DIR_LIST);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_DIR_LIST_LABEL);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_FILTER_LABEL);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_FILTER_TEXT);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_HELP_BUTTON);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_LIST);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_LIST_LABEL);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_OK_BUTTON);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_SELECTION_LABEL);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_SEPARATOR);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_TEXT);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
       w = XmFileSelectionBoxGetChild(f, XmDIALOG_WORK_AREA);
       XtVaSetValues(w, XmNbackground, g.main_bcolor, XmNforeground, g.main_fcolor,NULL);
   }
   c->wc = wc;
   //// Don't delete widgets here, delete at end of getfilename(s).
}


//--------------------------------------------------------------------//
//  fsscb                                                             //
//--------------------------------------------------------------------//
void fsscb(Widget w, XtP client_data, XmLCB *call_data)
{ 
   w=w; client_data=client_data;
   XmListCallbackStruct *ptr = call_data;
   int count = ptr->selected_item_count;
   char **tempstring=NULL;
   tempstring = new char *[count+1];
   XmStringGetLtoR(ptr->item, XmFONTLIST_DEFAULT_TAG, tempstring);
   if(strlen(tempstring[0])) strcpy(lestif_filename, tempstring[0]);
   delete[] tempstring;
}


//--------------------------------------------------------------------//
// fsokcb - callback for "ok" button in file selection box.           //
// Caller passes a clickboxinfo struct in client_data.                //
// Widget2 must be set to a pushbutton Widget or to NULL.             // 
// This is where memory is allocated for multifilename selector.      //
// The list array must be freed with delete[].                        //
// The filename strings must be freed with XtFree().                  //
//--------------------------------------------------------------------//
void fsokcb(Widget w, XtP client_data, XmFSBCB *call_data)
{
   call_data=call_data;
   Widget selectiontext;  // XmText for user to type in a filename 
   XmStringTable xmstrings;
   int k;
   clickboxinfo *c = (clickboxinfo *)client_data;
   char *filename; 
   char *fname;
   Widget button;

   //// Should never happen - clickbox already deleted
   if(c->done)
   {    message("Error in fsokcb", BUG); 
        fscancelcb(w, client_data, call_data);
        return;
   }

   filename = new char[FILENAMELENGTH];
   filename[0]=0;
   
   if(c->type == MULTIPLE)
   {   
       c->count=0;
       XtVaGetValues(c->listwidget, XmNselectedItemCount, &c->count, NULL); 

       ////  This returns the XmList items themselves, not a copy. The 
       ////  XmStringTable is automatically created by FileSelectionBox.
       ////  The application must not free the XmStrings (see OSF p. 1-859).
       
       XtVaGetValues(c->listwidget, XmNselectedItems, &xmstrings, NULL);

       c->list = new char*[c->count+1];
       for(k=0;k<c->count;k++)
       {
            ////  This allocates memory for items in list, use XtFree to free it.
            XmStringGetLtoR(xmstrings[k], XmFONTLIST_DEFAULT_TAG, &c->list[k]);
       }
       if(c->count>0) 
       {    strcpy(c->title, c->list[0]);
            strcpy(filename, c->list[0]);
       }else 
       {       //// A single click selects the file, then a double click deselects
               //// it and then comes here with nothing in the list. So retaliate 
               //// by copying selected filename (set in fsscb) out of a global.
               //// Also, with lestif, the fileselector doesn't recognize the 'Enter" key.
            selectiontext = XmFileSelectionBoxGetChild(w, XmDIALOG_TEXT);
               //// First check if they typed something in the text widget.
            XtVaGetValues(selectiontext, XmNvalue, &fname, NULL);
            if(strlen(fname)) strcpy(filename, fname);
               //// If it got nothing or a directory, substitute previous selection.
               //// Lestif might have unselected it so copy from the global.
            if(!strlen(filename) || filename[(int)strlen(filename)-1]=='/') 
                  strcpy(filename, lestif_filename);
            c->list[0] = XtMalloc(FILENAMELENGTH);  // Free this with XtFree()
            remove_trailing_space(filename);
            if(strlen(filename)) strcpy(c->title, filename);
            if(strlen(filename)) strcpy(c->list[0], filename);
       }
   }

   ////  For single file mode, Motif puts filename in an editable text widget. 
   if(c->type == SINGLE)
   {    selectiontext = XmFileSelectionBoxGetChild(w, XmDIALOG_TEXT);
        XtVaGetValues(selectiontext, XmNvalue, &fname, NULL);
        if(strlen(fname)) strcpy(filename, fname);
        //// In case user clicks Ok without selecting a file
        if(!strlen(filename) || filename[(int)strlen(filename)-1]=='/') 
             strcpy(filename, lestif_filename);
        remove_trailing_space(filename);
        if(strlen(filename)) strcpy(c->title, filename);
        c->count=1;
   }
   XtVaGetValues(c->listwidget, XmNtopItemPosition, &toppos, NULL);
   XFlush(g.display);

   ////  Put the new filename on the pushbutton. 
   ////  The pushbutton's XmNresizable resource must be False, otherwise
   ////  Motif will use this as an excuse to resize the entire dialog box.
   ////  Unmanage c->calling widget, which is the bulletin board - not w,
   ////  which is the filenamewidget on top.

   ////  c->widget[1] is the 'filename' pushbutton in dialogbox.
   ////  If calling from somewhere else, this should be set to NULL.
     
   ////  Focus goes to OK button when file is selected, so pressing Enter
   ////  twice will load the image.
   
   if(c->form != NULL) XmProcessTraversal(c->form, XmTRAVERSE_NEXT_TAB_GROUP); 

   //// Put the name in the pushbutton widget if it exists
   button = c->widget[1];
   if(button && strlen(c->title) && XtIsManaged(button)) 
        set_widget_label(button, basefilename(filename));

   dialoginfo *a = (dialoginfo*)c->ptr[0];
   if(a && strlen(c->path)) strcpy(a->path, c->path);

   c->done = 1;                            // Set flag indicating done
   delete[] filename;
   fscancelcb(w, client_data, call_data);
   g.escape = 0;
}


//--------------------------------------------------------------------//
// fscancelcb - callback for "cancel" button in file selection box.   //
//--------------------------------------------------------------------//
void fscancelcb(Widget w, XtP client_data, XmFSBCB *call_data)
{
   int k;
   w=w; call_data=call_data;  // Keep compiler quiet
   in_fscancelcb = 1;
   clickboxinfo *c = (clickboxinfo *)client_data;
   if(c==NULL) return;
   if(c->widget[0] == NULL) return;
   if(c->widget[0] && XtIsManaged(c->widget[0])) XtUnmanageChild(c->widget[0]);
   for(k=0;k<c->wc;k++) 
        if(!c->done && c->w[k]) XtDestroyWidget(c->w[k]);
   in_fscancelcb = 0;
   c->form = 0;
   c->done = 1;                            // Set flag indicating done
   g.escape = 1;
}


//--------------------------------------------------------------------//
// fsunmapcb - callback in case user deletes file selection box window//
//--------------------------------------------------------------------//
void fsunmapcb(Widget w, XtP client_data, XmFSBCB *call_data)
{
  g.block = 0; g.waiting=0;g.busy=0;
  if(!in_fscancelcb) fscancelcb(w, client_data, call_data);
}


//--------------------------------------------------------------------//
// fscdcb - callback for "chdir" button in file selection box.        //
//--------------------------------------------------------------------//
void fscdcb(Widget w, XtP client_data, XmFSBCB *call_data)
{
   w=w; call_data=call_data;  // Keep compiler quiet
   Widget f = (Widget)client_data;
   char *dir;
   int len;
   dir = new char[1024];
   XmString xms = XmStringCreateLtoR(dir, XmSTRING_DEFAULT_CHARSET);
   XtVaGetValues(f, XmNdirectory,  &xms, NULL);       
   XmStringGetLtoR(xms, XmFONTLIST_DEFAULT_TAG, &dir);
   chdir(dir);
   len = strlen(dir)-1;            // eliminate trailing /
   if(dir[len]=='/') dir[len]=0;
   strcpy(g.currentdir,dir);
   XmStringFree(xms);
   delete[] dir;
}


//--------------------------------------------------------------------//
// fsdirmaskcb - callback for changing dir mask in file selection box.//
//--------------------------------------------------------------------//
void fsdirmaskcb(Widget w, XtP client_data, XmFSBCB *call_data)
{
   w=w; call_data=call_data;  // Keep compiler quiet
   clickboxinfo *c = (clickboxinfo *)client_data;  
   XmString xmstring;
   XtVaGetValues(XtParent(w), XmNdirMask,  &xmstring, NULL);       
   if(c->dirmask != NULL)
        XmStringGetLtoR(xmstring, XmFONTLIST_DEFAULT_TAG, &c->dirmask);

   XtVaGetValues(XtParent(w), XmNdirectory,  &xmstring, NULL);       
   if(c->path != NULL)
        XmStringGetLtoR(xmstring, XmFONTLIST_DEFAULT_TAG, &c->path);
   XmStringFree(xmstring);
} 


//--------------------------------------------------------------------//
// getfilename                                                        //
//--------------------------------------------------------------------//
char *getfilename(char *oldtitle, char *path)
{  
   return getfilename(oldtitle, path, NULL);
}
char *getfilename(char *oldtitle, char *path, Widget widget)
{ 
   static char dirmask[FILENAMELENGTH]="*";
   int ostate = g.state;
   g.state = MESSAGE;
   int k;
   clickboxinfo c;
   c.title = oldtitle;
   c.helptopic = 0;
   c.done      = 0;
   c.wc        = 0;
   c.w         = new Widget[20];
   c.f1 = null;
   c.f2 = null;
   c.f3 = null;
   c.f4 = null;
   c.f5 = null;
   c.f6 = null;
   c.f7 = null;
   c.f8 = null;
   c.wc = 0;
   c.form = NULL;
   c.path = path;
   c.type = SINGLE;
   c.list = (char**)NULL;
   c.dirmask = new char[FILENAMELENGTH];
   strcpy(c.dirmask, dirmask);
   for(k=0; k<20; k++){ c.widget[k]=0; c.ptr[k]=0; }
   c.widget[1] = widget;

   ////  This changes c.wc
   filenamecb(g.main_widget, &c, (XmACB*)NULL);  
   g.waiting++;
   g.block++;
   while(!c.done) XtAppProcessEvent (g.app, XtIMAll);
   g.block = max(0, g.block-1);
   g.waiting = max(0, g.waiting-1);

   //// widgets are destroyed in fscancelcb
   XFlush(g.display);
   strcpy(dirmask, c.dirmask);
   delete[] c.w;
   delete[] c.dirmask;
   c.wc = 0;
   g.state = ostate;
   if(strlen(c.title)>0) return c.title;
   else return oldtitle;
}


//--------------------------------------------------------------------//
// getfilenames                                                       //
//--------------------------------------------------------------------//
void getfilenames(clickboxinfo *c)
{  
   static int ingfn=0;
   if(c==NULL) return;
   int k;
   c->done      = 0;
   if(ingfn){ c->done=1; return; }
   c->wc        = 0;
   ingfn=1;
   static char dirmask[FILENAMELENGTH]="*";
   c->type      = MULTIPLE;
   c->dirmask   = new char[FILENAMELENGTH];

   ////  Delete any previous list in case user clicks twice
   ////  Calling routine must still delete final list when finished.
   if(c->list!=NULL && c->count)
   {    for(k=0; k<c->count; k++) XtFree(c->list[k]);
        delete[] c->list;
   }
   c->count     = 0;
   strcpy(c->dirmask, dirmask);
   ////  This changes c->wc, allocates and fills c->list, and sets c->count.
   ////  Calling routine must delete c->list.
   filenamecb(g.main_widget, c, (XmACB*)NULL);   
   strcpy(dirmask, c->dirmask);
   ingfn=0;
}