1 /*
2  * $Id: x11merge.c,v 1.7 2003/02/16 12:43:37 isizaka Exp isizaka $
3  *
4  * This file is part of "Ngraph for X11".
5  *
6  * Copyright (C) 2002, Satoshi ISHIZAKA. isizaka@msa.biglobe.ne.jp
7  *
8  * "Ngraph for X11" is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * "Ngraph for X11" is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  */
23 
24 /**
25  *
26  * $Log: x11merge.c,v $
27  * Revision 1.7  2003/02/16 12:43:37  isizaka
28  * for release 6.13.18
29  *
30  * Revision 1.6  2002/07/06 08:57:25  isizaka
31  * change to GPL.
32  *
33  * Revision 1.5  1999/05/08 13:31:30  isizaka
34  * for release 6.03.02
35  *
36  * Revision 1.4  1999/04/15 12:14:26  isizaka
37  * for release 6.03.01
38  *
39  * Revision 1.3  1999/04/11 06:09:20  isizaka
40  * *** empty log message ***
41  *
42  * Revision 1.2  1999/03/20 12:32:54  isizaka
43  * minor change
44  *
45  * Revision 1.1  1999/03/17 13:29:01  isizaka
46  * Initial revision
47  *
48  *
49  **/
50 
51 #include <Xm/XmAll.h>
52 #include <X11/keysym.h>
53 #include <stdlib.h>
54 #include <stdio.h>
55 #include <unistd.h>
56 
57 #include "ngraph.h"
58 #include "object.h"
59 #include "nstring.h"
60 #include "ioutil.h"
61 
62 #include "x11gui.h"
63 #include "x11dialg.h"
64 #include "x11menu.h"
65 #include "ox11menu.h"
66 #include "x11file.h"
67 #include "x11merge.h"
68 #include "x11commn.h"
69 
MergeDialogSetupItem(Widget w,struct MergeDialog * d,int file,int id)70 void MergeDialogSetupItem(Widget w,struct MergeDialog *d,int file,int id)
71 {
72   if (file) {
73     SetTextFromObjField(w,"*file",d->Obj,id,"file");
74   }
75   SetTextFromObjField(w,"*topmargin",d->Obj,id,"top_margin");
76   SetTextFromObjField(w,"*leftmargin",d->Obj,id,"left_margin");
77   SetTextFromObjField(w,"*zoom",d->Obj,id,"zoom");
78 #ifdef JAPANESE
79   SetToggleFromObjField(w,"*GreekSymbol",d->Obj,id,"symbol_greek");
80 #endif
81 }
82 
MergeDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)83 void MergeDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
84 {
85   struct MergeDialog *d;
86 
87   d=(struct MergeDialog *)client_data;
88   d->ret=IDDELETE;
89 }
90 
MergeDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)91 void MergeDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)
92 {
93   struct MergeDialog *d;
94   int sel;
95 
96   d=(struct MergeDialog *)client_data;
97   if ((sel=CopyClick(d->widget,d->Obj,d->Id,FileCB))!=-1)
98     MergeDialogSetupItem(d->widget,d,FALSE,sel);
99 }
100 
MergeDialogSetup(Widget w,void * data,int makewidget)101 void MergeDialogSetup(Widget w,void *data,int makewidget)
102 {
103   Arg al[20];
104   Cardinal ac;
105   Widget rc,rc2,button;
106   struct MergeDialog *d;
107   char title[20];
108   XmString xs;
109 
110   d=(struct MergeDialog *)data;
111   sprintf(title,"Merge %d",d->Id);
112   xs=XmStringCreateLocalized(title);
113   XtVaSetValues(w,XmNdialogTitle,xs,NULL);
114   XmStringFree(xs);
115   if (makewidget) {
116   ac=0;
117   XtManageChild(button=XmCreatePushButton(w,"Close",al,ac));
118   XtAddCallback(button,XmNdisarmCallback,MergeDialogDelete,d);
119   ac=0;
120   XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
121   XtAddCallback(button,XmNdisarmCallback,MergeDialogCopy,d);
122 
123   ac=0;
124   XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
125   XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
126 
127   ac=0;
128   XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
129   XtManageChild(rc2=XmCreateRowColumn(rc,"filerc",al,ac));
130   ac=0;
131   XtManageChild(XmCreateLabel(rc2,"File",al,ac));
132   ac=0;
133   XtManageChild(XmCreateTextField(rc2,"file",al,ac));
134 
135   ac=0;
136   XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
137   XtManageChild(rc2=XmCreateRowColumn(rc,"marginrc",al,ac));
138   ac=0;
139   XtManageChild(XmCreateLabel(rc2,"TopMargin",al,ac));
140   ac=0;
141   XtManageChild(XmCreateTextField(rc2,"topmargin",al,ac));
142   ac=0;
143   XtManageChild(XmCreateLabel(rc2,"LeftMargin",al,ac));
144   ac=0;
145   XtManageChild(XmCreateTextField(rc2,"leftmargin",al,ac));
146   ac=0;
147   XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
148   XtManageChild(rc2=XmCreateRowColumn(rc,"zoomrc",al,ac));
149   ac=0;
150   XtManageChild(XmCreateLabel(rc2,"Zoom",al,ac));
151   ac=0;
152   XtManageChild(XmCreateTextField(rc2,"zoom",al,ac));
153 #ifdef JAPANESE
154   ac=0;
155   XtManageChild(XmCreateToggleButton(rc2,"GreekSymbol",al,ac));
156 #endif
157   }
158   MergeDialogSetupItem(w,d,TRUE,d->Id);
159 }
160 
MergeDialogClose(Widget w,void * data)161 void MergeDialogClose(Widget w,void *data)
162 {
163   struct MergeDialog *d;
164   int ret;
165 
166   d=(struct MergeDialog *)data;
167   if (d->ret!=IDOK) return;
168   ret=d->ret;
169   d->ret=IDLOOP;
170   if (SetObjFieldFromText(w,"*file",d->Obj,d->Id,"file")) return;
171   if (SetObjFieldFromText(w,"*topmargin",d->Obj,d->Id,"top_margin")) return;
172   if (SetObjFieldFromText(w,"*leftmargin",d->Obj,d->Id,"left_margin")) return;
173   if (SetObjFieldFromText(w,"*zoom",d->Obj,d->Id,"zoom")) return;
174 #ifdef JAPANESE
175   if (SetObjFieldFromToggle(w,"*GreekSymbol",
176       d->Obj,d->Id,"symbol_greek")) return;
177 #endif
178   d->ret=ret;
179 }
180 
MergeDialog(struct MergeDialog * data,struct objlist * obj,int id)181 void MergeDialog(struct MergeDialog *data,
182                  struct objlist *obj,int id)
183 {
184   data->SetupWindow=MergeDialogSetup;
185   data->CloseWindow=MergeDialogClose;
186   data->Obj=obj;
187   data->Id=id;
188 }
189 
CmMergeOpen()190 void CmMergeOpen()
191 {
192   struct objlist *obj;
193   char *name;
194   int id,ret;
195 
196   if (menulock || globallock) return;
197   if ((obj=chkobject("merge"))==NULL) return;
198   if (nGetOpenFileName(TopLevel,"Merge open","gra",NULL,NULL,&name,
199       "*.gra",TRUE,menulocal.changedirectory)==IDOK) {
200     if ((id=newobj(obj))>=0) {
201       changefilename(name);
202       putobj(obj,"file",id,name);
203       MergeDialog(&DlgMerge,obj,id);
204       ret=DialogExecute(TopLevel,&DlgMerge);
205       if ((ret==IDDELETE) || (ret==IDCANCEL)) {
206         delobj(obj,id);
207       } else NgraphApp.Changed=TRUE;
208     } else free(name);
209     MergeWinUpdate(TRUE);
210   }
211 }
212 
CmMergeClose()213 void CmMergeClose()
214 {
215   struct narray farray;
216   struct objlist *obj;
217   int i;
218   int num,*array;
219 
220   if (menulock || globallock) return;
221   if ((obj=chkobject("merge"))==NULL) return;
222   if (chkobjlastinst(obj)==-1) return;
223   SelectDialog(&DlgSelect,obj,FileCB,(struct narray *)&farray,NULL);
224   if (DialogExecute(TopLevel,&DlgSelect)==IDOK) {
225     num=arraynum(&farray);
226     array=(int *)arraydata(&farray);
227     for (i=num-1;i>=0;i--) {
228       delobj(obj,array[i]);
229       NgraphApp.Changed=TRUE;
230     }
231     MergeWinUpdate(TRUE);
232   }
233   arraydel(&farray);
234 }
235 
CmMergeUpdate()236 void CmMergeUpdate()
237 {
238   struct narray farray;
239   struct objlist *obj;
240   int i,j,ret;
241   int *array,num;
242 
243   if (menulock || globallock) return;
244   if ((obj=chkobject("merge"))==NULL) return;
245   if (chkobjlastinst(obj)==-1) return;
246   SelectDialog(&DlgSelect,obj,FileCB,(struct narray *)&farray,NULL);
247   if (DialogExecute(TopLevel,&DlgSelect)==IDOK) {
248     num=arraynum(&farray);
249     array=(int *)arraydata(&farray);
250     for (i=0;i<num;i++) {
251       MergeDialog(&DlgMerge,obj,array[i]);
252       if ((ret=DialogExecute(TopLevel,&DlgMerge))==IDDELETE) {
253         delobj(obj,array[i]);
254         for (j=i+1;j<num;j++) array[j]--;
255       }
256       if (ret!=IDCANCEL) NgraphApp.Changed=TRUE;
257     }
258     MergeWinUpdate(TRUE);
259   }
260   arraydel(&farray);
261 }
262 
263 
CmMergeMenu(Widget w,XtPointer client_data,XtPointer call_data)264 void CmMergeMenu(Widget w,XtPointer client_data,XtPointer call_data)
265 {
266   switch ((int )client_data) {
267   case 0:
268     CmMergeOpen();
269     break;
270   case 1:
271     CmMergeUpdate();
272     break;
273   case 2:
274     CmMergeClose();
275     break;
276   }
277 }
278 
MergeWinMergeOpen()279 void MergeWinMergeOpen()
280 {
281   CmMergeOpen();
282 }
283 
MergeWinMergeDelete()284 void MergeWinMergeDelete()
285 {
286   int sel;
287   struct MergeWin *d;
288 
289   d=&(NgraphApp.MergeWin);
290   if (menulock || globallock) return;
291   sel=d->select;
292   if ((sel>=0) && (sel<=d->filenum)) {
293     delobj(d->obj,sel);
294     MergeWinUpdate(FALSE);
295     NgraphApp.Changed=TRUE;
296   }
297 }
298 
MergeWinMergeCopy()299 void MergeWinMergeCopy()
300 {
301   int sel;
302   int j,id,perm,type;
303   char *field;
304   struct MergeWin *d;
305 
306   d=&(NgraphApp.MergeWin);
307   if (menulock || globallock) return;
308   sel=d->select;
309   if ((sel>=0) && (sel<=d->filenum)) {
310     if ((id=newobj(d->obj))>=0) {
311       for (j=0;j<chkobjfieldnum(d->obj);j++) {
312         field=chkobjfieldname(d->obj,j);
313         perm=chkobjperm(d->obj,field);
314         type=chkobjfieldtype(d->obj,field);
315         if ((strcmp2(field,"name")!=0)
316           && ((perm&NREAD)!=0) && ((perm&NWRITE)!=0) && (type<NVFUNC))
317           copyobj(d->obj,field,id,sel);
318       }
319       d->filenum++;
320       NgraphApp.Changed=TRUE;
321     }
322     d->select=sel;
323     MergeWinUpdate(FALSE);
324   }
325 }
326 
MergeWinMergeTop()327 void MergeWinMergeTop()
328 {
329   int sel;
330   struct MergeWin *d;
331 
332   d=&(NgraphApp.MergeWin);
333   if (menulock || globallock) return;
334   sel=d->select;
335   if ((sel>=0) && (sel<=d->filenum)) {
336     movetopobj(d->obj,sel);
337     d->select=0;
338     MergeWinUpdate(FALSE);
339     NgraphApp.Changed=TRUE;
340   }
341 }
342 
MergeWinMergeLast()343 void MergeWinMergeLast()
344 {
345   int sel;
346   struct MergeWin *d;
347 
348   d=&(NgraphApp.MergeWin);
349   if (menulock || globallock) return;
350   sel=d->select;
351   if ((sel>=0) && (sel<=d->filenum)) {
352     movelastobj(d->obj,sel);
353     d->select=d->filenum;
354     MergeWinUpdate(FALSE);
355     NgraphApp.Changed=TRUE;
356   }
357 }
358 
MergeWinMergeUp()359 void MergeWinMergeUp()
360 {
361   int sel;
362   struct MergeWin *d;
363 
364   d=&(NgraphApp.MergeWin);
365   if (menulock || globallock) return;
366   sel=d->select;
367   if ((sel>=1) && (sel<=d->filenum)) {
368     moveupobj(d->obj,sel);
369     d->select=sel-1;
370     MergeWinUpdate(FALSE);
371     NgraphApp.Changed=TRUE;
372   }
373 }
374 
MergeWinMergeDown()375 void MergeWinMergeDown()
376 {
377   int sel;
378   struct MergeWin *d;
379 
380   d=&(NgraphApp.MergeWin);
381   if (menulock || globallock) return;
382   sel=d->select;
383   if ((sel>=0) && (sel<=d->filenum-1)) {
384     movedownobj(d->obj,sel);
385     d->select=sel+1;
386     MergeWinUpdate(FALSE);
387     NgraphApp.Changed=TRUE;
388   }
389 }
390 
MergeWinMergeUpdate()391 void MergeWinMergeUpdate()
392 {
393   int sel,ret;
394   struct MergeWin *d;
395 
396   d=&(NgraphApp.MergeWin);
397   if (menulock || globallock) return;
398   sel=d->select;
399   if ((sel>=0) && (sel<=d->filenum)) {
400     MergeDialog(&DlgMerge,d->obj,sel);
401     if ((ret=DialogExecute(TopLevel,&DlgMerge))==IDDELETE) {
402       delobj(d->obj,sel);
403       d->select=-1;
404     }
405     if (ret!=IDCANCEL) NgraphApp.Changed=TRUE;
406     MergeWinUpdate(FALSE);
407   }
408 }
409 
MergeWinMergeSelect()410 void MergeWinMergeSelect()
411 {
412   int sel;
413   struct MergeWin *d;
414 
415   d=&(NgraphApp.MergeWin);
416   if (menulock || globallock) return;
417   sel=d->select;
418   if ((sel>=0) && (sel<=d->filenum)) Focus(d->obj,sel);
419 }
420 
MergeWinMergeHidden()421 void MergeWinMergeHidden()
422 {
423   int sel;
424   int hidden;
425   struct MergeWin *d;
426 
427   d=&(NgraphApp.MergeWin);
428   if (menulock || globallock) return;
429   UnFocus();
430   sel=d->select;
431   if ((sel>=0) && (sel<=d->filenum)) {
432     getobj(d->obj,"hidden",sel,0,NULL,&hidden);
433     hidden=hidden?FALSE:TRUE;
434     putobj(d->obj,"hidden",sel,&hidden);
435     MergeWinUpdate(FALSE);
436     NgraphApp.Changed=TRUE;
437   }
438 }
439 
MergeWinChangeFileNum()440 void MergeWinChangeFileNum()
441 {
442   struct MergeWin *d;
443 
444   d=&(NgraphApp.MergeWin);
445   if (d->text==NULL) return;
446   XtVaSetValues(d->text,XmNheight,(d->filenum+3)*FHeight,NULL);
447 }
448 
MergeWinUpdate(int clear)449 void MergeWinUpdate(int clear)
450 {
451   struct MergeWin *d;
452 
453   d=&(NgraphApp.MergeWin);
454   d->filenum=chkobjlastinst(d->obj);
455   MergeWinChangeFileNum();
456   if (d->text==NULL) return;
457   XClearArea(XtDisplay(d->text),XtWindow(d->text),0,0,0,0,TRUE);
458 }
459 
MergeWinExpose(Widget wi,XtPointer client_data,XtPointer call_data)460 void MergeWinExpose(Widget wi,XtPointer client_data,XtPointer call_data)
461 {
462   XmDrawingAreaCallbackStruct *dd;
463   XExposeEvent *e;
464   Display *disp;
465   Window win;
466   GC gc;
467   int i;
468   char buf[256];
469   char *file,*bfile;
470   XRectangle rect;
471   int h,w,x,y,len,cx;
472   int hidden;
473   struct MergeWin *d;
474 
475   d=&(NgraphApp.MergeWin);
476   if (d->text==NULL) return;
477   dd=(XmDrawingAreaCallbackStruct *)call_data;
478   e=(XExposeEvent *)(dd->event);
479   disp=e->display;
480   win=e->window;
481   gc=XCreateGC(disp,win,0,0);
482   if (globallock) return;
483   d->filenum=chkobjlastinst(d->obj);
484   h=FHeight;
485   w=FWidth;
486   XSetForeground(disp,gc,gray);
487   XFillRectangle(disp,win,gc,0,0,47*w+2*w,h);
488   x=FWidth;
489   y=FAscent;
490   XSetForeground(disp,gc,black);
491   rect.y=y-FAscent;
492   rect.height=h;
493   rect.x=x;
494   rect.width=6*w;
495   len=sprintf(buf,"#");
496   ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
497   x+=6*w;
498   rect.x=x;
499   rect.width=13*w;
500   len=sprintf(buf,"file");
501   ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
502   x+=13*w;
503   rect.x=x;
504   rect.width=6*w;
505   len=sprintf(buf,"    tm");
506   ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
507   x+=6*w;
508   rect.x=x;
509   rect.width=6*w;
510   len=sprintf(buf,"    lm");
511   ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
512   x+=6*w;
513   rect.x=x;
514   rect.width=6*w;
515   len=sprintf(buf,"    zm");
516   ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
517   x+=6*w;
518   rect.x=x+w;
519   rect.width=7*w;
520   len=sprintf(buf,"^#");
521   ExtTextOut(disp,win,gc,x+w,y,&rect,buf,len);
522 
523   for (i=0;i<=d->filenum;i++) {
524       x=w;
525       y=(i+1)*h+FAscent;
526       rect.y=y-FAscent;
527       rect.height=h;
528 
529       getobj(d->obj,"hidden",i,0,NULL,&hidden);
530       if (hidden) XSetForeground(disp,gc,gray);
531       else XSetForeground(disp,gc,black);
532       if (i==d->select) {
533         XSetForeground(disp,gc,black);
534         XFillRectangle(disp,win,gc,0,rect.y,74*w+h+w,rect.height);
535         XSetForeground(disp,gc,white);
536       }
537 
538       getobj(d->obj,"id",i,0,NULL,&cx);
539       rect.x=x;
540       rect.width=6*w;
541       len=sprintf(buf,"%d",cx);
542       ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
543       x+=6*w;
544 
545       getobj(d->obj,"file",i,0,NULL,&file);
546       bfile=getbasename(file);
547       rect.x=x;
548       rect.width=12*w;
549       if (bfile!=NULL) {
550         ExtTextOut(disp,win,gc,x,y,&rect,bfile,strlen(bfile));
551         memfree(bfile);
552       } else
553         ExtTextOut(disp,win,gc,x,y,&rect,"....................",20);
554       x+=13*w;
555 
556       getobj(d->obj,"top_margin",i,0,NULL,&cx);
557       rect.x=x;
558       rect.width=6*w;
559       len=sprintf(buf,"%6d",cx);
560       ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
561       x+=6*w;
562 
563       getobj(d->obj,"left_margin",i,0,NULL,&cx);
564       rect.x=x;
565       rect.width=6*w;
566       len=sprintf(buf,"%6d",cx);
567       ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
568       x+=6*w;
569 
570       getobj(d->obj,"zoom",i,0,NULL,&cx);
571       rect.x=x;
572       rect.width=6*w;
573       len=sprintf(buf,"%6d",cx);
574       ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
575       x+=6*w;
576 
577       getobj(d->obj,"oid",i,0,NULL,&cx);
578       rect.x=x+w;
579       rect.width=7*w;
580       len=sprintf(buf,"^%d",cx);
581       ExtTextOut(disp,win,gc,x+w,y,&rect,buf,len);
582       x+=8*w;
583     }
584   XFreeGC(disp,gc);
585 }
586 
MergeWinEvLButtonDown(unsigned int state,TPoint point,struct MergeWin * d)587 void MergeWinEvLButtonDown(unsigned int state,TPoint point,struct MergeWin *d)
588 {
589   int sel;
590 
591   if (menulock || globallock) return;
592   sel=point.y/FHeight-1;
593   if (sel!=d->select) {
594     MergeWinUpdate(FALSE);
595     d->select=sel;
596   }
597 }
598 
MergeWinEvLButtonDblClk(unsigned int state,TPoint point,struct MergeWin * d)599 void MergeWinEvLButtonDblClk(unsigned int state,TPoint point,struct MergeWin *d)
600 {
601   if (menulock || globallock) return;
602   MergeWinMergeUpdate();
603 }
604 
MergeWinEvRButtonDown(unsigned int state,TPoint point,struct MergeWin * d,XButtonPressedEvent * event)605 void MergeWinEvRButtonDown(unsigned int state,TPoint point,struct MergeWin *d,
606                           XButtonPressedEvent *event)
607 {
608   int sel;
609 
610   if (menulock || globallock) return;
611   sel=point.y/FHeight-1;
612   if (sel!=d->select) {
613     MergeWinUpdate(TRUE);
614     d->select=sel;
615   }
616   sel=d->select;
617   if ((sel>=0) && (sel<=d->filenum)) {
618     XtSetSensitive(XtNameToWidget(d->popup,"button_0"),False);
619     XtSetSensitive(XtNameToWidget(d->popup,"button_1"),True);
620     XtSetSensitive(XtNameToWidget(d->popup,"button_2"),True);
621     XtSetSensitive(XtNameToWidget(d->popup,"button_3"),True);
622     XtSetSensitive(XtNameToWidget(d->popup,"button_4"),True);
623     XtSetSensitive(XtNameToWidget(d->popup,"button_5"),True);
624     XtSetSensitive(XtNameToWidget(d->popup,"button_6"),True);
625     XtSetSensitive(XtNameToWidget(d->popup,"button_7"),True);
626     XtSetSensitive(XtNameToWidget(d->popup,"button_8"),True);
627     XtSetSensitive(XtNameToWidget(d->popup,"button_9"),True);
628   } else {
629     XtSetSensitive(XtNameToWidget(d->popup,"button_0"),True);
630     XtSetSensitive(XtNameToWidget(d->popup,"button_1"),False);
631     XtSetSensitive(XtNameToWidget(d->popup,"button_2"),False);
632     XtSetSensitive(XtNameToWidget(d->popup,"button_3"),False);
633     XtSetSensitive(XtNameToWidget(d->popup,"button_4"),False);
634     XtSetSensitive(XtNameToWidget(d->popup,"button_5"),False);
635     XtSetSensitive(XtNameToWidget(d->popup,"button_6"),False);
636     XtSetSensitive(XtNameToWidget(d->popup,"button_7"),False);
637     XtSetSensitive(XtNameToWidget(d->popup,"button_8"),False);
638     XtSetSensitive(XtNameToWidget(d->popup,"button_9"),False);
639   }
640   XmMenuPosition(d->popup,event);
641   XtManageChild(d->popup);
642 }
643 
644 Time MergeWinTime=0;
645 TPoint MergeWinPoint;
646 
MergeWinEvButtonDown(Widget w,XtPointer client_data,XEvent * event,Boolean * dispatch)647 void MergeWinEvButtonDown(Widget w,XtPointer client_data,XEvent *event,
648                          Boolean *dispatch)
649 {
650   struct MergeWin *d;
651   XButtonEvent *e;
652   TPoint point;
653   int dbl;
654 
655   d=(struct MergeWin *)client_data;
656   e=(XButtonEvent *)event;
657   point.x=e->x;
658   point.y=e->y;
659   if (((e->time-MergeWinTime)<menulocal.mouseclick)
660   && (MergeWinPoint.x==point.x) && (MergeWinPoint.y==point.y)) dbl=TRUE;
661   else dbl=FALSE;
662   MergeWinTime=e->time;
663   MergeWinPoint.x=point.x;
664   MergeWinPoint.y=point.y;
665   if (e->button==Button1) {
666     if (dbl) MergeWinEvLButtonDblClk(e->state,point,d);
667     else MergeWinEvLButtonDown(e->state,point,d);
668   } else if (e->button==Button2) {
669     MergeWinEvLButtonDown(e->state,point,d);
670     MergeWinEvLButtonDblClk(e->state,point,d);
671   } else if (e->button==Button3) MergeWinEvRButtonDown(e->state,point,d,e);
672 }
673 
MergeWinPopupMenu(Widget w,XtPointer client_data,XtPointer call_data)674 void MergeWinPopupMenu(Widget w,XtPointer client_data,XtPointer call_data)
675 {
676   switch ((int )client_data) {
677   case 0:
678     MergeWinMergeOpen();
679     break;
680   case 1:
681     MergeWinMergeSelect();
682     break;
683   case 2:
684     MergeWinMergeUpdate();
685     break;
686   case 3:
687     MergeWinMergeDelete();
688     break;
689   case 4:
690     MergeWinMergeTop();
691     break;
692   case 5:
693     MergeWinMergeUp();
694     break;
695   case 6:
696     MergeWinMergeDown();
697     break;
698   case 7:
699     MergeWinMergeLast();
700     break;
701   case 8:
702     MergeWinMergeCopy();
703     break;
704   case 9:
705     MergeWinMergeHidden();
706     break;
707   }
708 }
709 
MergeWinEvKeyDown(Widget w,XtPointer client_data,XEvent * event,Boolean * dispatch)710 void MergeWinEvKeyDown(Widget w,XtPointer client_data,XEvent *event,
711                      Boolean *dispatch)
712 {
713   struct MergeWin *d;
714   XKeyEvent *e;
715   KeySym sym;
716   int sel;
717 
718   if (menulock || globallock) return;
719   d=(struct MergeWin *)client_data;
720   e=(XKeyEvent *)event;
721   sym=XKeycodeToKeysym(e->display,e->keycode,0);
722   sel=d->select;
723   switch (sym) {
724   case XK_Down:
725     if (e->state & ShiftMask) MergeWinMergeDown();
726     else {
727       if ((sel==-1) && (d->filenum>=0)) sel=0;
728       else if (sel<d->filenum) sel++;
729       if (sel!=d->select) {
730         d->select=sel;
731         MergeWinUpdate(TRUE);
732       }
733     }
734     break;
735   case XK_Up:
736     if (e->state & ShiftMask) MergeWinMergeUp();
737     else {
738       if ((sel==-1) && (d->filenum>=0)) sel=d->filenum;
739       else if (sel>0) sel--;
740       if (sel!=d->select) {
741         d->select=sel;
742         MergeWinUpdate(TRUE);
743       }
744     }
745     break;
746   case XK_Delete:
747     MergeWinMergeDelete();
748     break;
749   case XK_Insert:
750     MergeWinMergeCopy();
751     break;
752   case XK_Home:
753     if (e->state & ShiftMask) MergeWinMergeTop();
754     break;
755   case XK_End:
756     if (e->state & ShiftMask) MergeWinMergeLast();
757     break;
758   case XK_Return:
759     MergeWinMergeUpdate();
760     break;
761   case XK_space:
762     MergeWinMergeSelect();
763     break;
764   case XK_BackSpace:
765     MergeWinMergeHidden();
766     break;
767   }
768 }
769 
MergeWindowUnmap(Widget w,XtPointer client_data,XtPointer call_data)770 void MergeWindowUnmap(Widget w,XtPointer client_data,XtPointer call_data)
771 {
772   struct MergeWin *d;
773   Position x,y,x0,y0;
774   Dimension w0,h0;
775 
776   d=&(NgraphApp.MergeWin);
777   if (d->Win!=NULL) {
778     XtVaGetValues(d->Win,XmNx,&x,XmNy,&y,
779                          XmNwidth,&w0,XmNheight,&h0,NULL);
780     menulocal.mergewidth=w0;
781     menulocal.mergeheight=h0;
782     XtTranslateCoords(TopLevel,0,0,&x0,&y0);
783     menulocal.mergex=x-x0;
784     menulocal.mergey=y-y0;
785     XtDestroyWidget(d->Win);
786     d->Win=NULL;
787     d->text=NULL;
788     XmToggleButtonSetState(XtNameToWidget(TopLevel,"*windowmenu.button_3"),
789                            False,False);
790   }
791 }
792 
CmMergeWindow(Widget w,XtPointer client_data,XtPointer call_data)793 void CmMergeWindow(Widget w,XtPointer client_data,XtPointer call_data)
794 {
795   Arg al[20];
796   Cardinal ac;
797   Widget dlg,scw,clip;
798   int width,height;
799   Position x,y;
800   struct MergeWin *d;
801 
802   d=&(NgraphApp.MergeWin);
803   if (d->Win!=NULL) {
804     XtUnmanageChild(d->Win);
805   } else {
806     if (menulocal.mergewidth==CW_USEDEFAULT) width=FWidth*47+2*FWidth;
807     else width=menulocal.mergewidth;
808     if (menulocal.mergeheight==CW_USEDEFAULT) height=FHeight*10;
809     else height=menulocal.mergeheight;
810     ac=0;
811     XtSetArg(al[ac],XmNborderWidth,1);ac++;
812     XtSetArg(al[ac],XmNdialogStyle,XmDIALOG_MODELESS); ac++;
813     XtSetArg(al[ac],XmNautoUnmanage,FALSE); ac++;
814     XtSetArg(al[ac],XmNwidth,width); ac++;
815     XtSetArg(al[ac],XmNheight,height); ac++;
816     if ((menulocal.mergex!=CW_USEDEFAULT)
817     && (menulocal.mergey!=CW_USEDEFAULT)) {
818       XtTranslateCoords(TopLevel,menulocal.mergex,menulocal.mergey,&x,&y);
819       x-=menulocal.framex;
820       y-=menulocal.framey;
821       if (x<0) x=0;
822       if (y<0) y=0;
823       XtSetArg(al[ac],XmNdefaultPosition,False); ac++;
824       XtSetArg(al[ac],XmNx,x); ac++;
825       XtSetArg(al[ac],XmNy,y); ac++;
826     } else {
827       XtSetArg(al[ac],XmNdefaultPosition,True); ac++;
828     }
829     XtManageChild(dlg=XmCreateFormDialog(TopLevel,"mergewindow",al,ac));
830     d->Win=dlg;
831     XtAddCallback(dlg,XmNunmapCallback,MergeWindowUnmap,NULL);
832     ac=0;
833     XtSetArg(al[ac],XmNtopAttachment,XmATTACH_FORM); ac++;
834     XtSetArg(al[ac],XmNbottomAttachment,XmATTACH_FORM); ac++;
835     XtSetArg(al[ac],XmNleftAttachment,XmATTACH_FORM); ac++;
836     XtSetArg(al[ac],XmNrightAttachment,XmATTACH_FORM); ac++;
837     XtSetArg(al[ac],XmNalignment,XmALIGNMENT_BEGINNING); ac++;
838     XtSetArg(al[ac],XmNscrollingPolicy,XmAUTOMATIC); ac++;
839     XtSetArg(al[ac],XmNscrollBarDisplayPolicy,XmSTATIC); ac++;
840     XtSetArg(al[ac],XmNwidth,width); ac++;
841     XtSetArg(al[ac],XmNheight,height); ac++;
842     XtSetArg(al[ac],XmNborderWidth,0);ac++;
843     XtManageChild(scw=XmCreateScrolledWindow(dlg,NULL,al,ac));
844     ac=0;
845     XtSetArg(al[ac],XmNwidth,FWidth*47+2*FWidth); ac++;
846     XtSetArg(al[ac],XmNheight,height); ac++;
847     XtSetArg(al[ac],XmNbackground,WhitePixel(XtDisplay(TopLevel),0)); ac++;
848     XtManageChild(d->text=XmCreateDrawingArea(scw,NULL,al,ac));
849     XtVaGetValues(scw,XmNclipWindow,&clip,NULL);
850     XtVaSetValues(clip,XmNbackground,WhitePixel(XtDisplay(TopLevel),0),NULL);
851     XtAddCallback(d->text,XmNexposeCallback,MergeWinExpose,NULL);
852     XtAddEventHandler(d->text,ButtonPressMask,False,MergeWinEvButtonDown,d);
853     d->obj=chkobject("merge");
854     d->filenum=chkobjlastinst(d->obj);
855     MergeWinChangeFileNum();
856     d->select=-1;
857     d->popup=XmVaCreateSimplePopupMenu(d->text,"mergepopup",MergeWinPopupMenu,
858     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
859     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
860     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
861     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
862     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
863     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
864     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
865     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
866     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
867     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
868     NULL);
869     XtAddEventHandler(d->text,KeyPressMask,False,MergeWinEvKeyDown,d);
870     XmToggleButtonSetState(XtNameToWidget(TopLevel,"*windowmenu.button_3"),
871                            True,False);
872   }
873 }
874