home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / suntar1.cpt / dialogs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  29.9 KB  |  1,202 lines

  1. /*******************************************************************************\
  2.  
  3. dialogs module
  4.  
  5. part of suntar, ⌐1991-92 Sauro & Gabriele Speranza
  6.  
  7. This program is public domain, feel free to use it or part of it for anything
  8.  
  9. \*******************************************************************************/
  10.  
  11. #include "antiglue.h"
  12. /* #include "system7.h" */
  13.  
  14. #include "windows.h"
  15. #include "suntar.h"
  16.  
  17. #include <string.h>
  18.  
  19. #define CONTROL_ON            1   /* Control value for on */
  20. #define CONTROL_OFF            0   /* Control value for off */
  21.  
  22. #define ESC 27
  23.  
  24. #define TITLEBARHEIGHT 20
  25.  
  26. #define obSet        1
  27. #define obSave        2
  28. #define obCancel    3
  29.  
  30. #define ob800         6
  31. #define obAlias         7
  32. #define obCreaDir     8
  33. #define obModiDate     10
  34. #define obUseSys7_SF 11
  35. #define obDelInc     12
  36. #define obTrunc14     13
  37. #define obUnderscore 14
  38. #define obSupprShell 15
  39. #define obVerify     16
  40. #define obSmallASCII 17
  41.  
  42. #define obFirstCheck    ob800
  43. #define obLastCheck        (obFirstCheck+last_check_option-first_check_option)
  44.  
  45. #define obTextCr    18
  46. #define obGIFCr        19
  47. #define obDelay        21
  48. #define obMinBeep    20
  49. #define obTarPopup    5
  50. #define obTarPopupTitle (obTarPopup-1)
  51. #define obWrASCPopup 22
  52.  
  53. #define sdFind        1
  54. #define sdExtract    2
  55. #define sdCancel    3
  56. #define sdScrollingList 4
  57.  
  58. #define fdFind        1
  59. #define fdCancel    2
  60. #define fdCheck        3
  61. #define fdSText        4
  62. #define fdText        5
  63.  
  64. #define mouseClicksDisabled -1
  65.  
  66. extern char FINITO[],DONE[];
  67.  
  68. void SetCheckBox(DialogPtr,short);
  69. void set_option_var(DialogPtr,short,Boolean    *);
  70. void get_option_var(DialogPtr,short,Boolean);
  71. void find_and_select(void);
  72. void select_list_filter(EventRecord *);
  73. void prepara_nome(char*,char*,long,short,short);
  74. static void list_updater(EventRecord *);
  75. static void list_activater(EventRecord *);
  76.  
  77.  
  78. static int button_code;
  79. DialogPtr ListDialog=NULL;
  80. static ListHandle LHandle;
  81. static Rect cornice;
  82. static Boolean at_start;
  83.  
  84.  
  85. pascal Boolean modal_filter (DialogPtr,EventRecord *,short *);
  86. static pascal Boolean modal_filter (theDialog,theEvent,itemHit)
  87. DialogPtr theDialog;
  88. register EventRecord *theEvent;
  89. short *itemHit;
  90. {
  91. /* unfortunately some events are simply ignored during some Toolbox calls:
  92. the event loop contained in the Alert or ModalDialog system routine can't know 
  93. how to handle update an activate routines for user windows; furthermore, even the 
  94. outline to the default button is not redrawn: if, for example, a screen saver 
  95. blanks the screen, the outline is lost because ModalDialog updates only what it 
  96. knows. Hence, I had to create an event filter for all modal dialogs, including
  97. standard file dialogs and Alert.
  98. Really, the best thing would be if Apple allowed to use the windowPic field in the window
  99. record in a different way: place there a pointer to an application-defined routine
  100. which handles updates and activates and is called implicitly by GetNextEvent, which 
  101. then will return false (so solving the problems for such events) and furthermore
  102. if a button could have a standard attribute "outlined" so that, DrawDialog could
  103. do the right job (that second thing seems to have been done, see TN 304).
  104. Another thing that GetNextEvent should do is calling FindWindow for mouseDown events,
  105. so that you get the information about which window was clicked even if that window
  106. was closed between the time of the click and the moment you get the event (for example,
  107. suntar 1.0 closed the about box when the Button function returned true, but the 
  108. mouseDown event remained in the event queue... In suntar 1.2, the same problem 
  109. has remained for the "going to background" dialog)
  110. */
  111. short    kind;
  112. Handle    h;
  113. Rect    r;
  114. switch(theEvent->what){
  115. case keyDown:
  116.     if((unsigned char)theEvent->message==CR || (unsigned char)theEvent->message==enter_key){
  117.         GetDItem(theDialog,1,&kind,&h,&r);
  118.         SelectButton(h);
  119.         *itemHit=1;
  120.         return true;
  121.         }
  122.     break;
  123. case updateEvt:
  124.     if((DialogPtr)theEvent->message==theDialog){
  125.         /* ModalDialog would do the update, but without OutlineControl... 
  126.         hence, I handle the event directly here */
  127.         WindowPtr w=NULL;
  128.         int item;
  129.         DialogSelect(theEvent,&w,&item);
  130.  
  131.         GetDItem(theDialog,1,&kind,&h,&r);
  132.         OutlineControl(h);
  133.         theEvent->what=nullEvent;
  134.         }
  135.     else
  136.         UpdateFilter(theEvent);
  137.     break;
  138. case activateEvt:
  139.     UpdateFilter(theEvent);
  140.     break;
  141. /* luckily, ModalDialog masks out disk insertions, so that they are received
  142. only after the dialog is closed: otherwise, I would not know what to
  143. do in that case... */
  144. }
  145.  
  146. return false;
  147. }
  148.  
  149. /* constants for positioning the default item within its box */
  150. #define leftSlop    13            /* leave this much space on left of title */
  151. #define rightSlop    5            /* this much on right */
  152. #define botSlop        5            /* this much below baseline */
  153.  
  154. extern MenuHandle tarPopupMenu,ntAPopupMenu;
  155. static short curr_tarpopup,curr_ntApopup;
  156.  
  157. pascal void redrawPopup(WindowPtr,short);
  158. static pascal void redrawPopup(theWindow,itemNo)
  159. WindowPtr theWindow;
  160. short itemNo;
  161. {
  162. /* inspired to Apple's Sample Code 006, but adding the triangle */
  163.     short    kind;
  164.     Handle    h;
  165.     Rect    r;
  166.     char    title[32];
  167.     MenuHandle menu_h;
  168.     short curr_item;
  169.     PolyHandle triangle;
  170.     #define triang_top    -12
  171.     #define triang_left  -18
  172. GetDItem(theWindow,itemNo,&kind,&h,&r);
  173.  
  174. if(itemNo==obTarPopup){
  175.     menu_h=tarPopupMenu;
  176.     curr_item=curr_tarpopup;
  177.     }
  178. else if(itemNo==obWrASCPopup){
  179.     menu_h=ntAPopupMenu;
  180.     curr_item=curr_ntApopup;
  181.     }
  182.  
  183. GetItem (menu_h,curr_item,&title);
  184. InsetRect(&r,-1,-1);        /* make it a little bigger */
  185.  
  186. /* draw the box and its drop shadow */
  187. FrameRect(&r);
  188. MoveTo(r.right,r.top+2); LineTo(r.right,r.bottom);
  189. LineTo(r.left+2,r.bottom);
  190. /* draw the string */
  191. MoveTo(r.left+leftSlop,r.bottom-botSlop);
  192. DrawString(title);
  193.  
  194. /* draw the triangle (according to the Guidelines of IM Vol 6) */
  195. triangle=OpenPoly();
  196. MoveTo(r.right+triang_left,r.bottom+triang_top);
  197. LineTo(r.right+triang_left+12, r.bottom+triang_top);
  198. LineTo(r.right+triang_left+6,r.bottom+triang_top+6);
  199. ClosePoly();
  200. FillPoly(triangle,black);
  201. KillPoly(triangle);
  202. }
  203.  
  204. pascal Boolean options_filter (DialogPtr,EventRecord *,short *);
  205. static pascal Boolean options_filter (theDialog,theEvent,itemHit)
  206. DialogPtr theDialog;
  207. register EventRecord *theEvent;
  208. short *itemHit;
  209. {
  210. short my_item;
  211.  
  212. if(theEvent->what==mouseDown){
  213.     GrafPtr    savePort;
  214.     Point mouseLoc= theEvent->where;
  215.     GetPort(&savePort);
  216.     SetPort(theDialog);
  217.     GlobalToLocal(&mouseLoc);
  218.  
  219.     my_item=FindDItem(theDialog, mouseLoc)+1;
  220.     
  221.     if ( my_item== obTarPopup || my_item==obWrASCPopup){
  222.         /* again, inspired to Apple's Sample Code 006 */
  223.         short    kind;
  224.         Handle    h;
  225.         Rect    r,promptBox;
  226.         Point popLoc;
  227.         long chosen;
  228.         MenuHandle menu_h;
  229.         short curr_item;
  230.  
  231.         if(my_item==obTarPopup){
  232.             GetDItem(theDialog,obTarPopupTitle,&kind,&h,&promptBox);
  233.             InvertRect(&promptBox);
  234.             menu_h=tarPopupMenu;
  235.             curr_item= curr_tarpopup;
  236.             }
  237.         else{
  238.             menu_h=ntAPopupMenu;
  239.             curr_item=curr_ntApopup;
  240.             }
  241.         InsertMenu(menu_h,-1);
  242.         GetDItem(theDialog,my_item,&kind,&h,&r);
  243.         popLoc = *(Point*)&r.top;
  244.         LocalToGlobal(&popLoc);
  245.         CalcMenuSize(menu_h); /*Work around Menu Mgr bug*/
  246.         EraseRect(&r);
  247.         chosen = PopUpMenuSelect(menu_h, popLoc.v, popLoc.h, curr_item);
  248.         if(my_item==obTarPopup){
  249.             InvertRect(&promptBox);
  250.             DeleteMenu(tarPopupID);
  251.             if(chosen) curr_tarpopup = loword(chosen);
  252.             }
  253.         else{
  254.             DeleteMenu(ntAPopupID);
  255.             if(chosen) curr_ntApopup = loword(chosen);
  256.             }
  257.     
  258.         InvalRect(&r);
  259.         theEvent->what=nullEvent;
  260.         }
  261.     SetPort(savePort);
  262.     return false;
  263.     }
  264. else if(theEvent->what==keyDown && (char)theEvent->message==ESC)
  265.     theEvent->what=nullEvent;    /* the dialog has no equivalent for Cancel,
  266.                                 if I don't remove it it will go in the text
  267.                                 (TextEdit does not know that ESC has a special
  268.                                 meaning) */
  269. else if(theEvent->what==keyDown && (theEvent->modifiers & cmdKey) ){
  270.     /* handle the edit commands in the dialog... */
  271.     if(((char)theEvent->message|0x20)=='c'){
  272.         DlgCopy (theDialog);
  273.         theEvent->what=nullEvent;
  274.         }
  275.     else if(((char)theEvent->message|0x20)=='x'){
  276.         DlgCut (theDialog);
  277.         theEvent->what=nullEvent;
  278.         }
  279.     if(((char)theEvent->message|0x20)=='v'){
  280.         if( TEGetScrapLen() <=8)
  281.             DlgPaste (theDialog);
  282.         else
  283.             SysBeep(5);        /* don't paste a very long string to a very small field */
  284.         theEvent->what=nullEvent;
  285.         }
  286.     return false;
  287.     }
  288. else
  289.     return modal_filter(theDialog,theEvent,itemHit);
  290. }
  291.  
  292. void options_box()
  293. {
  294. int i,currentRadio;
  295. Str255 buffer;
  296. /*EventRecord myEvent;*/
  297. DialogPtr myDialog;
  298. short        kind;
  299. Handle        h;
  300. Rect        r;
  301. short itemHit;
  302. AlertTHndl    alertHandle;
  303. SignedByte oldflags;
  304.  
  305. SetCursor(&arrow);
  306.  
  307. if (alertHandle = Get1Resource('DLOG',128)) {
  308.     oldflags=HGetState(alertHandle);
  309.     HNoPurge((Handle)alertHandle);
  310.     PositionDialog( &((**alertHandle).boundsRect));
  311.     }
  312. myDialog = GetNewDialog (128,NULL,(char*)-1);
  313.  
  314. if(myDialog!=NULL){
  315.     if(non_text_ASCII >3 ) non_text_ASCII=0;
  316.     #ifdef V_122
  317.     currentRadio= obFirstRadio+non_text_ASCII;
  318.     SetRadioButton(myDialog,currentRadio,CONTROL_ON);
  319.     #endif
  320.  
  321.     GetDItem(myDialog,obTextCr,&kind,&h,&r);
  322.     buffer[0]=4;
  323.     mcopy(&buffer[1],&text_creator,4);
  324.     SetIText(h,buffer);
  325.  
  326.     GetDItem(myDialog,obGIFCr,&kind,&h,&r);
  327.     buffer[0]=4;
  328.     mcopy(&buffer[1],&gif_creator,4);
  329.     SetIText(h,buffer);
  330.  
  331.     GetDItem(myDialog,obDelay,&kind,&h,&r);
  332.     my_itoa((long)delay_back,buffer);
  333.     c2pstr(buffer);
  334.     SetIText(h,buffer);
  335.  
  336.     GetDItem(myDialog,obMinBeep,&kind,&h,&r);
  337.     my_itoa((long)min_to_beep,buffer);
  338.     c2pstr(buffer);
  339.     SetIText(h,buffer);
  340.  
  341.     for(i=first_check_option;i<=last_check_option;i++){
  342.         if(i!=skip_check_option)
  343.             get_option_var(myDialog,obFirstCheck-first_check_option+i,options.opt_bytes[i]);
  344.         }
  345.  
  346.     GetDItem(myDialog,obTarPopup,&kind,&h,&r);
  347.     SetDItem (myDialog,obTarPopup, kind, (Handle)redrawPopup, &r);
  348.     curr_tarpopup=tar_version+1;
  349.     GetDItem(myDialog,obWrASCPopup,&kind,&h,&r);
  350.     SetDItem (myDialog,obWrASCPopup, kind, (Handle)redrawPopup, &r);
  351.     curr_ntApopup=non_text_ASCII+1;
  352.  
  353.     do {
  354.         ModalDialog(options_filter,&itemHit);
  355.         if(itemHit>=obFirstCheck && itemHit <= obLastCheck)
  356.             SetCheckBox(myDialog,itemHit);
  357.         #ifdef V_122
  358.         else if(itemHit>=obFirstRadio && itemHit <= obLastRadio){
  359.             SetRadioButton(myDialog,currentRadio,CONTROL_OFF);
  360.             SetRadioButton(myDialog,(currentRadio=itemHit),CONTROL_ON);
  361.             }
  362.         #endif
  363.         }
  364.     while (itemHit != obSave && itemHit != obCancel && itemHit != obSet );
  365.  
  366.     if( itemHit != obCancel){
  367.         GetDItem(myDialog,obTextCr,&kind,&h,&r);
  368.         GetIText(h,buffer);
  369.         for(i=buffer[0];i<=4;)
  370.             buffer[++i]=' ';
  371.         mcopy(&text_creator,&buffer[1],4);
  372.  
  373.         GetDItem(myDialog,obGIFCr,&kind,&h,&r);
  374.         GetIText(h,buffer);
  375.         for(i=buffer[0];i<=4;)
  376.             buffer[++i]=' ';
  377.         mcopy(&gif_creator,&buffer[1],4);
  378.  
  379.         GetDItem(myDialog,obDelay,&kind,&h,&r);
  380.         GetIText(h,buffer);
  381.         i= pstrtoi(buffer);
  382.         if(i>0 && i<20*60)
  383.             delay_back = i;
  384.  
  385.         GetDItem(myDialog,obMinBeep,&kind,&h,&r);
  386.         GetIText(h,buffer);
  387.         i= pstrtoi(buffer);
  388.         if(i>0)
  389.             min_to_beep = i;    
  390.  
  391.         for(i=first_check_option;i<=last_check_option;i++){
  392.             if(i!=skip_check_option)
  393.                 set_option_var(myDialog,obFirstCheck-first_check_option+i,&options.opt_bytes[i]);
  394.             }
  395.  
  396.         /*non_text_ASCII = currentRadio - obFirstRadio;*/
  397.         tar_version=curr_tarpopup-1;
  398.         non_text_ASCII=curr_ntApopup-1;
  399.  
  400.         if(itemHit==obSave) save_options();
  401.         }
  402.  
  403.     HSetState(alertHandle,oldflags);
  404.     DisposDialog(myDialog);
  405.     }
  406. }
  407.  
  408.  
  409. pascal void redrawList(WindowPtr,short);
  410. static pascal void redrawList(theWindow,itemNo)
  411. WindowPtr theWindow;
  412. short itemNo;
  413. {
  414.         LUpdate(((WindowPtr)ListDialog)->visRgn,LHandle);
  415.         FrameRect (&cornice);
  416. }
  417.  
  418. void select_and_extract()
  419. {
  420. /* this routine makes too many too different things, and the handling of
  421. AIX tar made things worst: it should be broken into at least two pieces,
  422. one handling the window and its list, the other one handling the tar/bar
  423. archive */
  424.  
  425. long length;
  426. Boolean more_files;
  427. Rect rView,dataBounds;
  428. int i,theCell;
  429. char buffer[150];
  430. Point myCell;
  431. int ci_stanno_certo;
  432. sector_t last_header;
  433. AlertTHndl    alertHandle;
  434. sector_t ** sectorList;
  435. Size sectListSize;
  436. SignedByte oldflags;
  437. static char s1[]="Nessun file parte qui\n", s2[]="No file starts in this disk\n";
  438.  
  439. ListDialog=NULL;
  440. LHandle=NULL;
  441. sectListSize=0;
  442. if(setjmp(main_loop)<0) {
  443.     if(ListDialog){
  444.         if(LHandle!=0) LDispose(LHandle);
  445.         DisposDialog(ListDialog);
  446.         remove_handlers(ListDialog);
  447.         ListDialog=NULL;
  448.         }
  449.     if(sectListSize) DisposHandle(sectorList);
  450.     return;
  451.     }
  452.  
  453. if(aspetta_inserzione(in_Italia?"\pInserisci il disco in formato UNIX":
  454.     "\pInsert the disk in UNIX format"))    return;
  455. if(di.is_not_initialized) return;
  456.  
  457. fase=reading_disk;
  458.  
  459. {
  460. enum formats fmt;
  461. previousFormat=tar_unknown;
  462. fmt=identify_format();
  463.  
  464. if(fmt==tar_format){
  465.     bar_archive=false;
  466.     last_header=0;
  467.     }
  468. else if(fmt==bar_format){
  469.     bar_archive=true;
  470.     floppy_n=untar_number( ((barh_type*)disk_buffer)->volume_num,true);
  471.     last_header= (untar_number( ((barh_type*)disk_buffer)->size,true)+1023)>>9;
  472.     }
  473. else{
  474.     diskEject();
  475.     return;        /* i messaggi sono giê comparsi... */
  476.     }
  477. }
  478.  
  479. if(last_header>=sectors_on_floppy){        /* only for bar... */
  480.     printf(in_Italia ? s1:s2);
  481.     return;
  482.     }
  483.  
  484. alertHandle = (AlertTHndl)Get1Resource('DLOG',131);
  485.  
  486. if (alertHandle) {
  487.     oldflags=HGetState(alertHandle);
  488.     HNoPurge((Handle)alertHandle);
  489.     (**alertHandle).boundsRect.top-=TITLEBARHEIGHT;
  490.     PositionDialog( &((**alertHandle).boundsRect));
  491.     (**alertHandle).boundsRect.top+=TITLEBARHEIGHT;
  492.     ListDialog=GetNewDialog(131,NULL,-1L);
  493.     SetWTitle (ListDialog,in_Italia?"\pSelezione files":"\pFile selection");
  494.     install_handlers(ListDialog,list_updater,list_activater);
  495.  
  496. /*printf("windowKind=%d\n",((WindowPeek)ListDialog)->windowKind); 2!*/
  497.     ((WindowPeek)ListDialog)->refCon= -2;
  498.  
  499.     SetPort(ListDialog);
  500.     {
  501.         static char *titoli[]={"\pTrova╔","\pEstrai","\pAnnulla"};
  502.         short    kind;
  503.         Handle    h;
  504.         Rect    r;
  505.         for(i=1;i<=3;i++){
  506.             GetDItem(ListDialog,i,&kind,&h,&r);
  507.             if(in_Italia) SetCTitle(h,titoli[i-1]);
  508.             HiliteControl(h, 255);
  509.             }
  510.         GetDItem(ListDialog,sdScrollingList,&kind,&h,&rView);
  511.         SetDItem (ListDialog,sdScrollingList, kind, (Handle)redrawList, &rView);
  512.     }
  513.  
  514.     /*TextFont(3);*/
  515.     {FontInfo    fInfo;
  516.     GetFontInfo(&fInfo);
  517.     i=fInfo.ascent+fInfo.descent+fInfo.leading;
  518.     }
  519.     rView.bottom= rView.top+ ((rView.bottom-rView.top)/i) * i;
  520.     cornice=rView;
  521.     InsetRect(&cornice,-1,-1);
  522.  
  523.     rView.right -= 15;
  524.     ci_stanno_certo= (rView.right-rView.left)/CharWidth('m');
  525.  
  526.     /*PenSize(1,1);*/
  527.     FrameRect (&cornice);
  528.  
  529.     dataBounds.top = 0;
  530.     dataBounds.left = 0;
  531.     dataBounds.bottom = 0;
  532.     dataBounds.right = 1;
  533.     LHandle = LNew(&rView,    /* position in window */
  534.                 &dataBounds,/* initial size of array */
  535.                 0L,            /* cell size (0 = default) */
  536.                 0,            /* resource ID of LDEF */
  537.                 ListDialog,    /* window pointer */
  538.                 true,        /* drawit */
  539.                 false,        /* has grow */
  540.                 false,        /* scrollHoriz */
  541.                 true);        /* scrollVert */
  542.  
  543.     (**LHandle).selFlags = lNoExtend | lNoRect | lUseSense | lExtendDrag | lNoNilHilite;
  544.  
  545.     for(;;){        /* loop on disks, for AIX only */
  546.         extern Boolean disco_espulso;
  547.         int files_on_floppy=0;
  548.         my_event_filter=select_list_filter;
  549.         theCell=0;
  550.         disco_espulso=false;
  551.         listonly=1;
  552.         while(last_header<sectors_on_floppy){
  553.             unsigned char linkflag;
  554.             /* printf ("leggo %ld\n",(long)last_header); */
  555.             check_events();
  556.             leggi_settore(last_header,disk_buffer);
  557.             if(check_error()) raise_error();
  558.  
  559.             sect_n=last_header;
  560.             if(check_all_zero(disk_buffer)){
  561.                 if(last_header==0||(bar_archive||hasVheader)&&last_header==1)
  562.                     printf(in_Italia?"Disco vuoto\n":"No data on disk\n");
  563.                 break;
  564.                 }
  565.  
  566.             linkflag=get_linkflag(&length);
  567.             if( linkflag=='\0'||linkflag=='0'||linkflag=='7' ){
  568.                 /*print_info(bar_archive ? ((barh_type*)disk_buffer)->name :
  569.                     ((tarh_type*)disk_buffer)->name,length);*/
  570.                 if(!sectListSize)
  571.                     sectorList= NewHandle(sectListSize=sizeof(sector_t));
  572.                 else
  573.                     SetHandleSize (sectorList, sectListSize+=sizeof(sector_t) );
  574.                 /* it should be:
  575.                 (*sectorList)[sectListSize/sizeof(sector_t)-1] = last_header;
  576.                 but optimizing:
  577.                 */
  578.                 *(sector_t*)(((char*)(*sectorList))+sectListSize-sizeof(sector_t)) = last_header;
  579.  
  580.                 theCell=LAddRow(1,theCell+1,LHandle);
  581.                 myCell.v=theCell;
  582.                 myCell.h=0;
  583.                 prepara_nome(
  584.                     bar_archive ? ((barh_type*)disk_buffer)->name : 
  585.                     ((tarh_type*)disk_buffer)->name,
  586.                     buffer, length, ci_stanno_certo, rView.right-rView.left);
  587.     
  588.                 LSetCell(buffer, strlen(buffer), myCell, LHandle);
  589.                 files_on_floppy++;
  590.                 }
  591.             last_header += (length+1023)/512;
  592.             }    /* end while */
  593.  
  594.         if(files_on_floppy==0){
  595.             if(last_header>=sectors_on_floppy)
  596.                 printf(in_Italia?s1:s2);
  597.             else
  598.                 printf(in_Italia?"Fine archivio\n":"End of archive\n");
  599.  
  600.             if(previousFormat==tar_GNU||previousFormat!=tar_AIX&&tar_version==tar_GNU||
  601.                last_header<sectors_on_floppy){
  602.                 diskEject();
  603.                 break;
  604.                 }
  605.             }
  606.         theCell=LAddRow(1,theCell+1,LHandle);    /* an empty cell, at the only purpose to
  607.             be able to click on it and deselect all other items: I hate not to
  608.             be able to return to that initial state ! */
  609.         myCell.v=theCell;
  610.         myCell.h=0;
  611.         LSetCell(buffer, 0, myCell, LHandle);
  612.         /*LDoDraw(true,LHandle); /* useful only if LNew had drawit = false */
  613.  
  614.         for(i=1;i<=3;i++){    /* riabilito i bottoni...*/
  615.             short        kind;
  616.             Handle        h;
  617.             Rect        r;
  618.             GetDItem(ListDialog,i,&kind,&h,&r);
  619.             HiliteControl(h, 0);
  620.             }
  621.         fase=ricevuto_comando;
  622.  
  623.         button_code=0;
  624.         while(!button_code){
  625.             extern long last_selection;
  626.             if(files_on_floppy!=0)
  627.                 MainEvent();
  628.             else
  629.                 button_code=sdExtract;
  630. /*            if(last_selection==menuItemMess(fileID,fmSelect)){
  631.                 if(ListDialog != FrontWindow() ) SelectWindow(ListDialog);
  632.                 last_selection=0;
  633.                 }
  634. */
  635.             if(button_code==sdFind){
  636.                 find_and_select();
  637.                 button_code=0;
  638.                 }
  639.             else if(button_code==sdExtract){
  640.                 myCell.v=0;
  641.                 more_files=LGetSelect(true,&myCell,LHandle);
  642.                 if(myCell.v==theCell)    /* Å la cella vuota in fondo
  643.                                     --the empty cell */
  644.                     more_files=false;
  645.                 if(more_files)
  646.                     select_directory();
  647.                 else
  648.                     reply.good=true;
  649.                 if( !reply.good || !more_files&&(tar_version!=tar_AIX||previousFormat==tar_GNU))
  650.                     button_code=0;
  651.                 }
  652.             accept_abort_command();
  653.             }
  654.  
  655.         if(button_code==sdCancel)
  656.             break;
  657.         if(button_code==sdExtract){    /* se sono qui, ho giê selezionato il folder
  658.                     e ho giê trovato il primo item selezionato
  659.                     -- note that some operations handling that event have been
  660.                     performed inside the item-event loop above */
  661.             for(i=1;i<=3;i++){    /* disabilito i bottoni...*/
  662.                 short        kind;
  663.                 Handle        h;
  664.                 Rect        r;
  665.                 GetDItem(ListDialog,i,&kind,&h,&r);
  666.                 HiliteControl(h, 255);
  667.                 }
  668.             /* avverti il filtro di non accettare click sulla lista:
  669.             -- disable the handling of the list by the event filter
  670.             */
  671.             button_code = mouseClicksDisabled;
  672.             listonly=0;
  673.             fase=selected_reading;
  674.             while(more_files){
  675. /* il get va fatto prima, sia per non chiedere destinazione se nessuno Å selezionato,
  676. sia per togliere la finestra prima di iniziare l'ultima estrazione
  677. -- find next file selected before extracting the current one: there are a couple of 
  678. reasons to do that before rather than after
  679. */
  680.                 Point curr_cell;
  681.                 /*
  682.                 i=sizeof(buffer);
  683.                 LGetCell(buffer,&i,myCell,LHandle);
  684.                 buffer[i]=0;
  685.                 printf("%d:%s [%ld]\n",myCell.v,buffer,(long)(*sectorList)[myCell.v]);
  686.                 */
  687.                 sect_n = (*sectorList)[myCell.v];
  688.  
  689.                 curr_cell = myCell;
  690.                 myCell.v++;
  691.                 more_files=LGetSelect(true,&myCell,LHandle);
  692.                 if(myCell.v==theCell) more_files=false;
  693.                 if(!more_files&& (tar_version!=tar_AIX || previousFormat==tar_GNU || last_header<sectors_on_floppy) ){
  694.                     /* tolgo il dialogo subito, per non rischiare di fare confusione se 
  695.                         dovesse saltar fuori anche il dialogo di disk insert
  696.                         -- remove the dialog before starting extracting the last file,
  697.                         that reduces the confusion in case the disk insertion dialog appears...
  698.                         */
  699.                     LDispose(LHandle);
  700.                     LHandle=NULL;
  701.                     DisposDialog(ListDialog);
  702.                     remove_handlers(ListDialog);
  703.                     ListDialog=NULL;
  704.                     my_event_filter=NULL;
  705.                     }
  706.  
  707.                 leggi_settore(sect_n,&disk_buffer);
  708.                 if(check_error()) raise_error();
  709.  
  710.                 listonly=0;
  711.                 if(bar_archive)
  712.                     unbar();
  713.                 else
  714.                     untar();
  715.                 if(ListDialog){        /* deseleziono il nome del file appena salvato...
  716.                                 -- deselect the file name */
  717.                     LSetSelect(false,curr_cell,LHandle);
  718.                     LAutoScroll(LHandle);
  719.                     }
  720.                 }
  721.             if(tar_version==tar_AIX && last_header>=sectors_on_floppy){
  722.                 /* svuota la lista !
  723.                 -- delete the current items in the list... */
  724.                 LDelRow (0,0,LHandle);
  725.                 sectListSize=0;
  726.                 /* non c'Å bisogno di deallocare sectorList perchÄ tanto ci
  727.                 penserê la SetHandleSize */
  728.                 /* get next disk */
  729.                 last_header-=sectors_on_floppy;
  730.                 if(!disco_espulso){
  731.                     riprova:
  732.                     diskEject();
  733.                     if(aspetta_inserzione(in_Italia?
  734.                         "\pInserisci il prossimo disco tar":
  735.                         "\pInsert next tar disk")) break;
  736.                     if(di.is_not_initialized) goto riprova;    /* cannot use a do-while,
  737.                             the above break must exit from another loop... */
  738.                     }
  739.                 else
  740.                     last_header=sect_n;
  741.                 previousFormat=tar_AIX;
  742.                 button_code=0;
  743.                 fase=reading_disk;
  744.                 }
  745.             else{
  746.                 printf(in_Italia?FINITO:DONE);
  747.                 fine_lavoro();
  748.                 break;
  749.                 }
  750.             }
  751.         }
  752.  
  753.     HSetState(alertHandle,oldflags);
  754.     if(ListDialog){
  755.         LDispose(LHandle);
  756.         DisposDialog(ListDialog);
  757.         remove_handlers(ListDialog);
  758.         ListDialog=NULL;
  759.         }
  760.     if(sectListSize) DisposHandle(sectorList);
  761.     }
  762.  
  763. my_event_filter=NULL;
  764. }
  765.  
  766. static void prepara_nome(name_ptr, buffer, length, ci_stanno_certo, pixel_size)
  767. /* modify the file name so that it contains the file size and fits within the
  768. limited space of the list */
  769. char *name_ptr;
  770. register char *buffer;
  771. long length;
  772. int ci_stanno_certo,pixel_size;
  773. {
  774. int ln,ls,l;
  775. char len_buff[20];
  776.  
  777. len_buff[0]=' ';
  778. len_buff[1]='(';
  779. if(length>9999){
  780.     my_itoa((long)((length+512)>>10),&len_buff[2]);
  781.     ls=strlen(len_buff);
  782.     strcpy(&len_buff[ls]," Kbyt");
  783.     ls += 5;
  784.     }
  785. else{
  786.     my_itoa((long)length,&len_buff[2]);
  787.     ls=strlen(len_buff);
  788.     strcpy(&len_buff[ls]," byt");
  789.     ls += 4;
  790.     }
  791.     
  792. ln=strlen(name_ptr);
  793.  
  794. mcopy(buffer,name_ptr,ln);
  795. mcopy(&buffer[ln],len_buff,ls+1);
  796.  
  797. if(ln+ls > ci_stanno_certo){
  798.     register int i;
  799.     GrafPtr    savePort;
  800.  
  801.     GetPort( &savePort );
  802.     SetPort( ListDialog );    /* perchÄ Å dalla GrafPort che StringWidth deduce
  803.                             font e size da usare... */
  804.     c2pstr(buffer);
  805.     i=1;
  806.     while(StringWidth(buffer)>pixel_size){
  807.         while(i<ln && buffer[i]!='/') i++;
  808.         if(i>=ln) break;    /* non c'Å nessun path da tagliare, meglio lasciare
  809.                             cosô come Å */
  810.         buffer[1]='╔';
  811.         mcopy(&buffer[2],&buffer[i],ln+ls-i+2);
  812.         buffer[0] -= i-2; ln -= i-2;
  813.         i=3;    /* per non ritrovare lo stesso'/' */
  814.         }
  815.     p2cstr(buffer);
  816.     SetPort( savePort );
  817.     }
  818. mcopy(&buffer[ln+ls],"es)",6);
  819. }
  820.  
  821. pascal short my_search(char *,char *,int,int);
  822. static pascal short my_search(p1,p2,l1,l2)
  823. register char *p1,*p2;
  824. register int l1,l2;
  825. {
  826. int i=0;
  827. #define bufsize 80
  828. unsigned char buffer[bufsize];
  829. register unsigned char *p;
  830.  
  831. if(!l1) return 1;
  832.  
  833. /* i nomi sono passati attraverso prepara_nome, quindi devo cominciare col
  834. togliere il numero di bytes
  835. -- P2 is the search string, in lowercase. P1 is the string installed in the list, 
  836. which was not converted to lowercase and was altered by prepara_nome so that it
  837. contains the byte count in parentheses: it's better to extract the meaningful
  838. part, translating to lowercase, and in order to use strncmp do that as a C string
  839. */
  840. while(l1>0 && p1[--l1]!='(')
  841.     ;
  842. l1--;    /* lo spazio... */
  843. p=&buffer[bufsize-1];
  844. *p='\0';
  845. while(l1>0 && p1[--l1] != '/'){
  846.     if(p1[l1]>='A' && p1[l1]<='Z')
  847.         *--p = p1[l1] + 'a'-'A';
  848.     else
  849.         *--p = p1[l1];
  850.     }
  851.  
  852. /*printf("!%s!\n",p); */
  853.  
  854. while(*p){
  855.     if(!strncmp(p,p2,(size_t)l2) ) return 0;
  856.     if(at_start) return 1;
  857.     p++;
  858.     }
  859. return 1;
  860. }
  861.  
  862. static void find_and_select()
  863.  
  864. /* handle the find dialog and the find operation */
  865. {
  866. Str255 buffer;
  867. DialogPtr myDialog;
  868. short        kind;
  869. Handle        h;
  870. Rect        r;
  871. short itemHit;
  872.  
  873. {
  874. AlertTHndl    alertHandle;
  875. register Rect *p;
  876. short vs,hs;
  877. GrafPtr savePort;
  878. SignedByte oldflags;
  879.  
  880. alertHandle = (AlertTHndl)Get1Resource('DLOG',135);
  881. oldflags=HGetState(alertHandle);
  882. HNoPurge((Handle)alertHandle);
  883.  
  884. /* center the dialog near the Find button from which it was generated */
  885.  
  886. GetPort(&savePort);
  887. SetPort(ListDialog);
  888.  
  889. GetDItem(ListDialog,sdFind,&kind,&h,&r);
  890.  
  891. LocalToGlobal(&r);        /* really, r.topLeft */
  892.  
  893. p= &(**alertHandle).boundsRect;
  894. vs= p->bottom - p->top;
  895. hs= p->right - p->left;
  896.  
  897. if( (p->top=r.top-80)<(kind=MBARHEIGHT+15))
  898.     p->top=kind;
  899. else if(p->top > (kind=screenHeight-vs-15))
  900.     p->top = kind;
  901.  
  902. if( (p->left=r.left-50)<15)
  903.     p->left=15;
  904. else if(p->left > (kind=screenWidth-hs-15))
  905.     p->left = kind;
  906.  
  907. p->bottom=p->top+vs;
  908. p->right=p->left+hs;
  909. SetPort(savePort);
  910.  
  911. myDialog = GetNewDialog (135,NULL,(char*)-1);
  912. HSetState(alertHandle,oldflags);
  913. }
  914.  
  915. if(myDialog!=NULL){
  916.     if(in_Italia){
  917.         static char* titoli[]={"\pTrova","\pNon trovare",
  918.             "\pil testo Å all\'inizio del nome","\pSeleziona i nomi contenenti" };
  919.         int i;
  920.         for(i=fdFind;i<fdSText;i++){
  921.             GetDItem(myDialog,i,&kind,&h,&r);
  922.             SetCTitle(h,titoli[i-fdFind]);
  923.             }
  924.         GetDItem(myDialog,fdSText,&kind,&h,&r);
  925.         SetIText(h,titoli[3]);
  926.         }
  927. /* handle the dialog */
  928.     do {
  929.  
  930.         ModalDialog(modal_filter,&itemHit);
  931.         if(itemHit==fdCheck)
  932.             SetCheckBox(myDialog,itemHit);
  933.         } 
  934.     while (itemHit != fdFind && itemHit != fdCancel );
  935.  
  936.     GetDItem(myDialog,fdText,&kind,&h,&r);
  937.     GetIText(h,buffer);
  938.     GetDItem(myDialog,fdCheck,&kind,&h,&r);
  939.     at_start = GetCtlValue(h);
  940.  
  941.     DisposDialog(myDialog);
  942.  
  943.     if(itemHit==fdFind){
  944.         register int i;
  945.         Point myCell;
  946.  
  947.         if(buffer[0]!=0){
  948.             for(i=1;i<=buffer[0];i++)
  949.                 if(buffer[i]>='A'&&buffer[i]<='Z') buffer[i] += 'a'-'A';
  950.                 /* if(buffer[i]=='/') ???? */
  951.             /* buffer[buffer[0]+1]='\0'; */
  952.  
  953.             myCell.v=myCell.h=0;
  954.             while( LSearch(&buffer[1],buffer[0],my_search,&myCell,LHandle)){
  955.                 /*printf("%d,%d\n",myCell.v,myCell.h);*/
  956.                 LSetSelect(true,myCell,LHandle);
  957.                 myCell.v++;
  958.                 }
  959.             LAutoScroll(LHandle);
  960.             }
  961.         /*printf("%d:%p\n",at_start,buffer);*/
  962.         }
  963.     }
  964. }
  965.  
  966. static void list_updater(theEvent)
  967. EventRecord *theEvent;
  968. {
  969. short j;
  970. DialogPtr w=NULL;
  971. DialogSelect(theEvent,&w,&j);
  972. }
  973.  
  974. static void list_activater(theEvent)
  975. EventRecord *theEvent;
  976. {
  977. if(theEvent->modifiers & activeFlag) SetPort( ListDialog );
  978. LActivate((theEvent->modifiers & activeFlag)!=0,LHandle);
  979. }
  980.  
  981. static void select_list_filter(theEvent)
  982. register EventRecord *theEvent;
  983. {
  984. int i,j;
  985.  
  986. switch(theEvent->what){
  987. /* no, non c'Å un bottone di default ! e devo lasciare attivi i comandi
  988. case keyDown:
  989. case autoKey:
  990.     if((unsigned char)theEvent->message==CR || (unsigned char)theEvent->message==enter_key)
  991.         button_code=1;
  992.     theEvent->what=nullEvent;
  993.     break;
  994.     */
  995. case mouseDown:
  996.     {
  997.     WindowPtr whichWindow;
  998.     int i;
  999.  
  1000.     i=FindWindow( theEvent->where, &whichWindow );
  1001.     if(whichWindow==(WindowPtr)ListDialog){
  1002.         GrafPtr    savePort;
  1003.  
  1004.         GetPort( &savePort );
  1005.         SetPort( ListDialog );
  1006.         switch(i){
  1007.         case inContent:
  1008.             if (whichWindow != FrontWindow() )
  1009.                 SelectWindow(whichWindow);
  1010.             else{
  1011.                 Point localPt = theEvent->where;
  1012.                 ControlHandle     theControl;
  1013.  
  1014.                 GlobalToLocal(&localPt);
  1015.  
  1016.                 if (localPt.h > cornice.right+5){
  1017. #if 0
  1018.                     if( (FindControl(localPt, whichWindow, &theControl)) != 0) {
  1019.                         if(TrackControl(theControl, localPt, 0L)){
  1020.                             short        kind;
  1021.                             Handle        h;
  1022.                             Rect        r;
  1023.                             short i=0;
  1024.                             do
  1025.                                 GetDItem(ListDialog,++i,&kind,&h,&r);
  1026.                             while(h!=theControl && i<=3);
  1027.                             if(h==theControl)
  1028.                                 button_code=i;
  1029.                             }
  1030.                         }
  1031. #endif
  1032.                     if( IsDialogEvent(theEvent)){
  1033.                         if(DialogSelect(theEvent,&ListDialog,&j))
  1034.                             button_code=j;
  1035.                         }
  1036.                     }
  1037.                 else{
  1038.                      if(button_code!=mouseClicksDisabled || localPt.h > cornice.right-15){
  1039.                         /*int doubleClick;*/
  1040.                         /*doubleClick =LClick(localPt,theEvent->modifiers,LHandle); */
  1041.                         /* should check for double clicks here */
  1042.                         LClick(localPt,theEvent->modifiers,LHandle);
  1043.                         }
  1044.                     }
  1045.                 }
  1046.             break;
  1047.         case inDrag:
  1048.             SetPort(savePort);    /* MainEvent lo gestisce correttamente */
  1049.             return;
  1050.         }
  1051.         theEvent->what=nullEvent;
  1052.         SetPort(savePort);
  1053.         }
  1054.     }
  1055.     break;
  1056. }
  1057. }
  1058.  
  1059.  
  1060.  
  1061. void my_alert()
  1062. /* a centered alert, with an "OK" button */
  1063. {
  1064. AlertTHndl    alertHandle;
  1065. SignedByte oldflags;
  1066.  
  1067. check_foreground();
  1068. alertHandle = (AlertTHndl)Get1Resource('ALRT',ErrorAlert);
  1069. oldflags=HGetState(alertHandle);
  1070. HNoPurge((Handle)alertHandle);
  1071. PositionDialog( &((**alertHandle).boundsRect));
  1072. SetCursor(&arrow);
  1073. Alert(ErrorAlert, modal_filter);    /* we've tried to use NoteAlert &Co, but
  1074.     the icon has the same feature of the button outline, it disappears
  1075.     when a screen saver blanks the screen (even without our event filter):
  1076.     to avoid that, one must add an icon item to the DITL, and not to use
  1077.     NoteAlert at all */
  1078. HSetState(alertHandle,oldflags);
  1079. }
  1080.  
  1081.  
  1082.  
  1083. short my_modal_dialog(dialog_ID,titoli_italiani,n_titoli)
  1084. /* A centered modal dialog. It may display button titles in both
  1085. English and Italian
  1086. */
  1087. char **titoli_italiani;
  1088. {
  1089.     DialogPtr myDialog;
  1090.     short item;
  1091.     AlertTHndl    alertHandle;
  1092.     short    kind;
  1093.     Handle    h;
  1094.     Rect    r;
  1095.     SignedByte oldflags;
  1096.  
  1097.     check_foreground();
  1098.     SetCursor(&arrow);
  1099.  
  1100.     alertHandle = (AlertTHndl)Get1Resource('DLOG',dialog_ID);
  1101.     if (alertHandle) {
  1102.         oldflags=HGetState(alertHandle);
  1103.         HNoPurge((Handle)alertHandle);
  1104.         PositionDialog( &((**alertHandle).boundsRect));
  1105.         myDialog=GetNewDialog(dialog_ID,NULL,-1L);
  1106.         if(in_Italia && titoli_italiani){
  1107.             int fatti=0;
  1108.             for(item=1;fatti<n_titoli;item++){
  1109.                 GetDItem(myDialog,item,&kind,&h,&r);
  1110.                 if((kind&0x7F)==ctrlItem+btnCtrl){
  1111.                     SetCTitle(h,*titoli_italiani++);
  1112.                     fatti++;
  1113.                     }
  1114.                 }
  1115.             }
  1116.         ModalDialog(modal_filter,&item);
  1117.  
  1118.         HSetState(alertHandle,oldflags);
  1119.         DisposDialog(myDialog);
  1120.         return item;
  1121.         }
  1122. }
  1123.  
  1124.  
  1125. static void set_option_var(dialog,item,var)
  1126.     DialogPtr    dialog;
  1127.     short        item;
  1128.     Boolean        *var;
  1129. {
  1130.     short        kind;
  1131.     Handle        h;
  1132.     Rect        r;
  1133.  
  1134.     GetDItem(dialog,item,&kind,&h,&r);
  1135.     *var = GetCtlValue(h);
  1136. }
  1137.  
  1138. static void get_option_var(dialog,item,var)
  1139.     DialogPtr    dialog;
  1140.     short        item;
  1141.     Boolean        var;
  1142. {
  1143.     short        kind;
  1144.     Handle        h;
  1145.     Rect        r;
  1146.  
  1147.     GetDItem(dialog,item,&kind,&h,&r);
  1148.     SetCtlValue(h,var);
  1149. }
  1150.  
  1151. void SetCheckBox(dialog,item)
  1152.     DialogPtr    dialog;
  1153.     short        item;
  1154. {
  1155.     short        kind;
  1156.     Handle        h;
  1157.     Rect        r;
  1158.  
  1159.     GetDItem(dialog,item,&kind,&h,&r);
  1160.     SetCtlValue((ControlHandle)h,!GetCtlValue(h));
  1161. }
  1162.  
  1163. int dialogo_tipo_file()
  1164. {
  1165. int i,currentRadio;
  1166. DialogPtr myDialog;
  1167. short        kind;
  1168. Handle        h;
  1169. Rect        r;
  1170. short itemHit;
  1171. AlertTHndl    alertHandle;
  1172. SignedByte oldflags;
  1173.  
  1174. #define first_radio 3
  1175.  
  1176. if (alertHandle = Get1Resource('DLOG',134)) {
  1177.     oldflags=HGetState(alertHandle);
  1178.     HNoPurge((Handle)alertHandle);
  1179.     PositionDialog( &((**alertHandle).boundsRect));
  1180.     }
  1181. myDialog = GetNewDialog (134,NULL,(char*)-1);
  1182.  
  1183. if(myDialog!=NULL){
  1184.  
  1185.     currentRadio= first_radio;
  1186.     SetRadioButton(myDialog,currentRadio,CONTROL_ON);
  1187.  
  1188.     do {
  1189.         ModalDialog(modal_filter,&itemHit);
  1190.         if(itemHit!=1){
  1191.             SetRadioButton(myDialog,currentRadio,CONTROL_OFF);
  1192.             SetRadioButton(myDialog,(currentRadio=itemHit),CONTROL_ON);
  1193.             }
  1194.         }
  1195.     while (itemHit != 1 );
  1196.  
  1197.     HSetState(alertHandle,oldflags);
  1198.     DisposDialog(myDialog);
  1199.     }
  1200. return currentRadio-first_radio;
  1201. }
  1202.