home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / ArchiveUtils / JumpBack / Source / TwoPassUIControl.m < prev   
Encoding:
Text File  |  1995-06-12  |  9.8 KB  |  480 lines

  1.  
  2. //======================================================================
  3. //
  4. //    Portions written by FreemanSoft Inc.
  5. //
  6. //    FreemanSoft disclaims any warranty of any kind, expressed or implied,
  7. //    as to this source code's fitness for any particular use.
  8. //
  9. //    For more information, use the following electronic mail addresses:
  10. //     
  11. //        info@FreemanSoft.com    general questions
  12. //        support@FreemanSoft.com    technical questions
  13. //
  14. //======================================================================
  15.  
  16.  
  17. /* Written by
  18.  *    Joe Freeman    jfreeman@next.com    
  19.  *    TwoPassUIControl
  20.  *
  21.  *    This code has no warranty.  
  22.  *    It is provided so that the consumer may maintain and modify it
  23.  *    at their own risk.  Use this code at your own risk.
  24.  */
  25.  
  26. #import "TwoPassUIControl.h"
  27.  
  28. #import "DragView.h"
  29. #import "Subprocess.h"
  30. ///#import "PreferencesPanel.h"
  31. #import "pathutil.h"
  32.  
  33. #import "common.h"
  34.  
  35. #import "twoPassUI.h"        // strings entries
  36.  
  37.  
  38. /*================================================================
  39.  *    Private methods 
  40.  *================================================================*/
  41.  
  42. @implementation TwoPassUIControl(Private)
  43.  
  44. /* updates currentState and title */
  45. - setState:(int)newState
  46. {
  47.     switch (newState){
  48.         case NOTHING_RUNNING:
  49.         [theWindow setTitle:title_string];
  50.         currentState = newState;
  51.         break;
  52.     case PASS_1_RUNNING:
  53.         [theWindow setTitle:title_pass_1];
  54.         currentState = newState;
  55.         break;
  56.     case PASS_2_RUNNING:
  57.         [theWindow setTitle:title_pass_2];
  58.         currentState = newState;
  59.         break;
  60.     default: /* invalid state so pick other */
  61.         [theWindow setTitle:title_string];
  62.         [self setState: NOTHING_RUNNING];
  63.         break;
  64.     }
  65.  
  66.     return self;
  67. }
  68.  
  69. @end
  70.  
  71. @implementation TwoPassUIControl
  72.  
  73. /*================================================================
  74.  *    all strings related to rdist are right before runPassTwo: 
  75.  *================================================================*/
  76.  
  77.     
  78. /*================================================================
  79.  *    initializers 
  80.  *================================================================*/
  81. - init
  82. {
  83.     static windowPosX = 0;
  84.     static windowPosY = 0;
  85.     NXRect windowRect;
  86.     
  87.     [super init];
  88.     
  89.     [self setState: NOTHING_RUNNING];
  90.     canContinue = YES;            /* redundant */
  91.     
  92.     [NXApp loadNibSection: "TwoPassUIControl.nib" owner:self];
  93.     [theWindow getFrame:&windowRect];
  94.     windowRect.origin.x+=windowPosX;
  95.     windowRect.origin.y-=windowPosY;
  96.     if (windowPosX < 120){
  97.     windowPosX+= 20.0;
  98.     windowPosY+= 20.0;
  99.     } else {
  100.     windowPosX =  0.0;
  101.     windowPosY =  0.0;
  102.     }
  103.     [theWindow moveTo:windowRect.origin.x :windowRect.origin.y];
  104.     [theWindow setTitle:title_string];
  105.     [theWindow makeKeyAndOrderFront:self];
  106.     return self;
  107. }
  108.  
  109. - initSourcePath:(char *)srcPath destinationPath:(char *)destPath
  110. {
  111.     [self init];
  112.     if (srcPath && *srcPath){
  113.         if (srcPath[0] == '~'  ){
  114.         strcpy(sPathList, NXHomeDirectory());
  115.         strcat(sPathList, &srcPath[1]);
  116.     }else {
  117.             strcpy(sPathList, srcPath);
  118.     }
  119.     }
  120.     
  121.     if (destPath && *destPath){
  122.         if (destPath[0] == '~' ){
  123.         strcpy(dPathList, NXHomeDirectory());
  124.         strcat(dPathList, &destPath[1]);
  125.     } else {
  126.             strcpy(dPathList, destPath);
  127.     }
  128.     }
  129.     
  130.     [self updateTextFields:self];
  131.     [self updateIconViews:self];
  132.     return self;
  133. }
  134.  
  135.  
  136. /*================================================================
  137.  *    outlet connection
  138.  *================================================================*/
  139.  
  140. - window
  141. {
  142.     return theWindow;
  143. }
  144.  
  145. - (int)state
  146. {
  147.     return currentState;
  148. }
  149.  
  150. - (const char *)buttonImageName
  151. {
  152.     return "JumpBack_notext.tiff";
  153. }
  154.  
  155. - (const char *)buttonAltImageName
  156. {
  157.     return "JumpBack_abort.tiff";
  158. }
  159.  
  160. - (const char *)stringsTable
  161. {
  162.     return "twoPassUI";
  163. }
  164.  
  165.  
  166. - setStartButton:anObject
  167. {
  168.     startButton = anObject;
  169.     [NXImage findImageNamed:     [self buttonImageName]];
  170.     [startButton setIcon:     [self buttonImageName]];
  171.     [NXImage findImageNamed:     [self buttonAltImageName]];
  172.     [startButton setAltIcon:     [self buttonAltImageName]];
  173.     return self;
  174. }
  175.  
  176. /* ===========================
  177.  * Utility methods
  178.  * ===========================*/
  179.  
  180.     /*
  181.      * default behavior says to just use the whole path typed in 
  182.      */
  183. - updateFromTextFields:sender
  184. {
  185.     strcpy(dPathList, [destinationText stringValue]);
  186.     strcpy(sPathList, [sourceText stringValue]);
  187.     return self;
  188. }
  189.     
  190.  
  191. /* simple standard case where all paths are absolute
  192.  */
  193. - updateTextFields:sender
  194. {
  195.     [sourceText     setStringValue:sPathList];
  196.     [destinationText     setStringValue:dPathList];
  197.     return self;
  198. }
  199.  
  200. - updateIconViews:sender
  201. {
  202.     [sourceDragView        useIconForFile:sPathList];
  203.     [destinationDragView    useIconForFile:dPathList];
  204.     return self;
  205. }
  206.  
  207. /* show a string in the log window */
  208. - logIt:(const char *)s
  209. {
  210.     int    numChars = [logText textLength];
  211.     [[[logText setSel:numChars :numChars] replaceSel:s] scrollSelToVisible];
  212.     NXPing();
  213.     return self;
  214. }
  215.  
  216.  
  217. /* ===========================
  218.  * Target/Action stuff
  219.  * ===========================*/
  220.  
  221. #define    rhost_string    \
  222.      "/bin/echo localhost `whoami` | /bin/cat >> ~/.rhosts; /usr/bin/sort ~/.rhosts | /usr/bin/uniq > /tmp/$$ ; /bin/mv /tmp/$$ ~/.rhosts"
  223.  
  224. - startProcess:sender
  225. {
  226.     canContinue=YES;
  227.     if ([sender state] == 1){
  228.     [logText selectText:self];
  229.     [logText replaceSel:startup_string];
  230.     
  231.     if ( !sPathList || !*sPathList){
  232.         [self logIt:missing_source];
  233.         [sender setState:0];
  234.         return nil;
  235.     }
  236.     if ( !dPathList || !*dPathList) {
  237.         [self logIt:missing_dest];
  238.         [sender setState:0];
  239.         return nil;
  240.     }
  241.         
  242.     /* really should scan the rhosts files to make sure this will work */
  243.     system(rhost_string);
  244.     
  245.     /* run find (which will spawn rdist), or just run rdist */
  246.     if (![self runPassOne:self])
  247.         [self runPassTwo:self];
  248.     
  249.     } else [self abortProcess:self];
  250.     return self;
  251. }
  252.  
  253. /* default is no pass one */
  254. - runPassOne:sender
  255. {
  256.     return nil;
  257. }
  258.  
  259. - runPassTwo:sender
  260. {
  261.     return self;
  262. }
  263.  
  264.  
  265. - abortProcess:sender
  266. {
  267.     [self setState: NOTHING_RUNNING];
  268.     canContinue = NO;
  269.     [subprocessObj terminate:sender ];
  270.     [self logIt: abort_string];
  271.     [startButton setState:0];
  272.     return self;
  273. }
  274.  
  275.  
  276. /*=======================================
  277.  *
  278.  * drag support 
  279.  *
  280.  *=======================================*/
  281.  
  282. - iconEntered:where
  283. {
  284.     [theWindow setTitle:almost_got_it];
  285.     return self;
  286. }
  287.  
  288. - iconLeft:where
  289. {
  290.     [theWindow setTitle:title_string];
  291.     return self;
  292. }
  293.  
  294. - iconDropped:where
  295. {
  296.     if (sPathList)
  297.         [theWindow setTitle:basename(sPathList)];
  298.     else
  299.     [theWindow setTitle:title_string];
  300.     return self;
  301. }
  302.  
  303. - iconBogus:where
  304. {
  305.     [theWindow setTitle:bogus_file_type];
  306.     NXBeep();
  307.     return self;
  308. }
  309.  
  310. - (BOOL) isFilePBValid:(Pasteboard *)pboard forView:sender
  311. {
  312.     int length;
  313.     const char * tPathList;
  314.  
  315.     [pboard readType:NXFilenamePboardType data:&tPathList length:&length];
  316.     if (!isDirectory((char *)tPathList))
  317.         return NO;
  318.     else
  319.         return YES;
  320. }
  321.     
  322.  
  323. - (BOOL) acceptedFilePB:(Pasteboard *)pboard forView:sender
  324. {
  325.     int length;
  326.     const char * tPathList;
  327.     
  328.     
  329.     [pboard readType:NXFilenamePboardType data:&tPathList length:&length];
  330.     if (!isDirectory((char *) tPathList))
  331.     {
  332.     NXRunAlertPanel([NXApp appName],
  333.         bogus_file_type,
  334.         "OK",NULL,NULL);
  335.         return NO;
  336.     }
  337.     else
  338.     {
  339.     if (sender == destinationDragView)
  340.     {
  341.             strcpy(dPathList, tPathList);
  342.     }
  343.     else
  344.     {
  345.             strcpy(sPathList, tPathList);
  346.     }
  347.     [self updateTextFields:self];
  348.     }
  349.     return YES;
  350. }    
  351.  
  352. - userClicked:(int)numTimes at:(NXPoint *)clickPoint inDragView:sender;
  353. {
  354.     const char *ourPath;
  355.     if (sender == destinationDragView)
  356.     {
  357.          ourPath = dPathList;
  358.     }
  359.     else if (sender == sourceDragView)
  360.     {
  361.          ourPath = sPathList;
  362.     } else
  363.     {
  364.         return nil;
  365.     }
  366.     
  367.     if (numTimes == 1)
  368.         [[Application workspace] selectFile:ourPath
  369.                 inFileViewerRootedAt:""];
  370.     else if (numTimes == 2)
  371.         [[Application workspace] openFile:ourPath
  372.                 fromImage: [sender currentImage]
  373.                 at:clickPoint
  374.                 inView:sender];
  375.     return self;
  376. }
  377. /* ===========================
  378.  * subprocess delegation
  379.  * ===========================*/
  380.  
  381.  
  382. - subprocessOutput:(char *)buffer
  383. {
  384.     char    *copyBuf;    
  385.  
  386.     copyBuf = buffer;
  387.     if (currentState == PASS_1_RUNNING){
  388.         /*
  389.          *    The find only returns offensive directories 
  390.          *     if we get anything back from the find,
  391.          *     it means we have found something bad
  392.          */
  393.         if (debug_level >= debug_except_pat)
  394.                     fprintf(stderr,"find returned: %s\n", copyBuf);
  395.         if (canContinue) {
  396.             /* 
  397.              * this is the first one to be found bad
  398.              */
  399.             [self logIt: pass_1_found_something];
  400.         }
  401.         /* log the offensive directory names */
  402.         [self logIt: copyBuf];
  403.         /* do this so rdist doesn't run later */
  404.         canContinue = NO;
  405.         /* we don't abort the find cause we want to see them all */
  406.     } else if (currentState == PASS_2_RUNNING) {
  407.         [self logIt: buffer];
  408.     } else {
  409.         /* I'm confused unknown state */
  410.     }
  411.      return self;
  412. }
  413.  
  414. - subprocessDone
  415. {
  416.     if (currentState == PASS_1_RUNNING){
  417.         /* if find was running and found no problems */
  418.         if (canContinue) {
  419.             [self runPassTwo:self];
  420.         } else {
  421.             [self abortProcess:self];
  422.         }
  423.     } else if (currentState == PASS_2_RUNNING){
  424.         [self setState: NOTHING_RUNNING];
  425.         [self logIt:finished_string];
  426.         [startButton setState:0];
  427.     } else {
  428.         /* I'm confused, unknown state */
  429.     }
  430.     return self;
  431. }
  432.  
  433.  
  434. /* ===========================
  435.  * window delegation
  436.  * ===========================*/
  437.  
  438. - windowWillClose:sender
  439. {
  440.     id retID;
  441.     
  442.     if ([startButton state] == 1)
  443.     {
  444.         if (    NXRunAlertPanel([NXApp appName],
  445.         process_running,
  446.         dont_close, close_anyway,NULL) == NX_ALERTDEFAULT )
  447.     {
  448.         retID= nil;
  449.     }
  450.     else
  451.     {
  452.         [self abortProcess:self];
  453.         retID= self;
  454.     }
  455.  
  456.     }
  457.     else
  458.     {
  459.         retID= self;
  460.     }
  461.     if (retID == self) {
  462.         [self free];
  463.     [sender setDelegate:nil];
  464.     }
  465.     return retID;
  466. }
  467.  
  468. /* ===========================
  469.  * text delegation
  470.  * ===========================*/
  471.  
  472. - textDidEnd:textObject endChar:(unsigned short)whyEnd
  473. {
  474.     [ self updateFromTextFields:self];
  475.     [ self updateIconViews:self];
  476.     return self;
  477. }
  478.  
  479. @end
  480.