home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Utilities / Fiend-1.4.1-src / Controller.m < prev    next >
Encoding:
Text File  |  1997-05-29  |  31.1 KB  |  1,131 lines

  1. #import <pwd.h>
  2. #import <math.h>
  3. #import "Fiend.h"
  4. #import "FiendWraps.h"
  5. #import "Controller.h"
  6. #import "ProgressView.h"
  7. #import "Dock.h"
  8. #import "DockMgrView.h"
  9. #import "ShelfView.h"
  10. #import "IconView.h"
  11. #import "Thinker.h"
  12. #import "Password.h"
  13. #import <misckit/misckit.h>
  14. //#import <otikit/smartkit.h>
  15.  
  16. @interface MenuCell(LazyEnable)
  17. - lazySetEnabled:(BOOL)flag;
  18. @end
  19.  
  20. @implementation MenuCell(LazyEnable)
  21. - lazySetEnabled:(BOOL)flag
  22. {
  23.     if ([self isEnabled] != flag)
  24.         [self setEnabled:flag];
  25.     return self;
  26. }
  27. @end
  28.  
  29. @implementation Controller
  30.  
  31. + initialize
  32. {
  33.     static NXDefaultsVector defaults = {
  34.         {"LBX", "50"},
  35.         {"LBY", "13"},
  36.         {"LBW", "11"},
  37.         {"LBH", "11.5"},
  38.         {"RBX", "51"},
  39.         {"RBY", "4.0"},
  40.         {"RBW", "10"},
  41.         {"RBH", "10"},
  42.         {"LIX", "55.0"},
  43.         {"LIY", "38.0"},
  44.         {"LIR", "1.8"},
  45.         {SGRID_VALUE, "64"},
  46.         {DGRID_VALUE, "64"},
  47.         {SCAN_TIME, "0.5"},
  48.         {GRID_ENABLE, "NO"},
  49.         {USE_SOUND, "YES"},
  50.         {SHOW_DOCK, "YES"},
  51.         {TILE_IMAGE, "NO"},
  52.         {CUR_DOCK, "1"},
  53.         {SIZE_FONT, "YES"},
  54.         {HIDE_ICONS, "YES"},
  55.         {SHOW_SELPNL, "YES"},
  56.         {SHOW_PROG, "YES"},
  57.         {SHOW_DCKIDX, "YES"},
  58.         {ENAB_DCLCK, "YES"},
  59.         {ENAB_SCLCK, "YES"},
  60.         {SINK_DOCK, "NO"},
  61.         {FOLLOW_LEVS, "NO"},
  62.         {ENAB_BSPACE, "YES"},
  63.         {ENAB_SHELF, "YES"},
  64.         {CPST_SHLF, "NO"},
  65.         {DRAW_TNAIL, "YES"},
  66.         {LIMIT_SHLF, "NO"},
  67.         {DSTRICT_COPY, "NO"},
  68.         {SSTRICT_COPY, "NO"},
  69.         {SHELF_APPTIL, "NO"},
  70.         {CLOSE_PSTLNCH, "NO"},
  71.         {CLOSE_PSTACT, "YES"},
  72.         {SHOW_CUES, "YES"},
  73.         {PTAB_RETRIES, "20"},
  74.         {ACTIVE_DELAY, "0.5"},
  75.         {DOCK_BLDFNT, "YES"},
  76.         {DOCK_BIGFNT, "NO"},
  77.         {DOCK_LOCKED, "NO"},
  78.         {IMAGE_NAME, DEFAULT_IMAGE_NAME},
  79.         {DCKUPR_LEVEL, "6"},
  80.         {DCKLWR_LEVEL, "-1"},
  81.         {SHELF_LEVEL, "-31000"},
  82.         {"DisableLazyLoad", "NO"},
  83.         {"PreLaunchDelay", "250"},
  84. //        {"DockPromiscuous", "NO"},
  85. #ifdef hppa
  86.         {REDSP_SHLF, "YES"},
  87. #else
  88.         {REDSP_SHLF, "NO"},
  89. #endif
  90.         {NULL}
  91.     };
  92.  
  93.     NXRegisterDefaults([NXApp appName], defaults);
  94.     NXSetDefault("BackSpace", "windowType", "0");
  95.     return self;
  96. }
  97.  
  98. - delayedAutolaunch
  99. {
  100.     [dockMgrView performAutolaunches];
  101.     return self;
  102. }
  103.  
  104. - delayedAppDidInit:sender
  105. {
  106.     int                i;
  107.     id                dockWindow;
  108.     int                  screenCount;
  109.     char            string[200];
  110.     NXScreen        *screens;
  111.     id                shelfWindow = NULL;
  112.     NXRect            iconRect = {{400.0, 400.0}, {64.0, 64.0}};
  113.     NXRect            screenRect = {{0.0, 0.0}, {0.0, 0.0}};
  114.     NXRect            contentRect = {{0.0, 0.0}, {0.0, 0.0}};
  115.     int                lowerLevel = atoi(NXGetDefaultValue([NXApp appName], DCKLWR_LEVEL));
  116.     int                upperLevel = atoi(NXGetDefaultValue([NXApp appName], DCKUPR_LEVEL));
  117.     int                shelfLevel = atoi(NXGetDefaultValue([NXApp appName], SHELF_LEVEL));
  118.     float            preLaunchDelay = atof(NXGetDefaultValue([NXApp appName], "PreLaunchDelay"));
  119.     float            dgridValue = atof(NXGetDefaultValue([NXApp appName], DGRID_VALUE));
  120.     BOOL            sinkDock = !strcmp(NXGetDefaultValue([NXApp appName], SINK_DOCK), "YES");
  121.     BOOL            limitShelf = !strcmp(NXGetDefaultValue([NXApp appName], LIMIT_SHLF), "YES");
  122.     BOOL            showProgress = !strcmp(NXGetDefaultValue([NXApp appName], SHOW_PROG), "YES");
  123.     BOOL            shelfEnabled = !strcmp(NXGetDefaultValue([NXApp appName], ENAB_SHELF), "YES");
  124.     BOOL            redisplayShelf = !strcmp(NXGetDefaultValue([NXApp appName], REDSP_SHLF), "YES");
  125.     BOOL            backSpaceEnabled = !strcmp(NXGetDefaultValue([NXApp appName], ENAB_BSPACE), "YES");
  126.     const char         *returnTypes[] = {NXFilenamePboardType, NXAsciiPboardType, NULL};
  127.     const char         *sendTypes[] = {NXFilenamePboardType, NULL};
  128.  
  129.     [NXApp hide:self];
  130.     [NXApp preventWindowOrdering];
  131.     [NXApp registerServicesMenuSendTypes:sendTypes andReturnTypes:returnTypes];
  132.     [[NXApp appListener] setServicesDelegate:self];
  133.  
  134.     [NXApp getScreens:&screens count:&screenCount];
  135.     for(i = 0; i < screenCount; i++)
  136.         NXUnionRect(&screens[i].screenBounds, &screenRect);
  137.  
  138.     if (showProgress)    {
  139.         if (shelfEnabled)
  140.             [[progressField setStringValue:PROG_SHELF] display];
  141.         else
  142.             [[progressField setStringValue:PROG_DOCK] display];
  143.         [progressPanel center];
  144.         [progressPanel makeKeyAndOrderFront:self];
  145.         [progressPanel setFloatingPanel:YES];
  146.     }
  147.  
  148.     if (shelfEnabled)    {
  149.         shelfWindow = [[Window allocFromZone:NXCreateZone(vm_page_size, vm_page_size, YES)]
  150.                                 initContent:&screenRect
  151.                                 style:NX_TOKENSTYLE
  152.                                 backing:NX_BUFFERED buttonMask:0 defer:NO];
  153.  
  154.         if (limitShelf)    {
  155.             [shelfWindow setDepthLimit:NX_TwelveBitRGBDepth];
  156.             [shelfWindow setDynamicDepthLimit:YES];
  157.         }
  158.         shelfView = [ShelfView allocFromZone:[shelfWindow zone]];
  159.         [IconView resetCachedShelfImages];
  160.         [shelfView initFrame:&screenRect];
  161.         [[shelfWindow setContentView:shelfView] free];
  162.         [shelfWindow setAvoidsActivation:YES];
  163.  
  164.         PSsetwindowlevel(shelfLevel, [shelfWindow windowNum]);
  165.         [shelfWindow display];
  166.         [shelfWindow orderBack:self];
  167.         if (redisplayShelf)
  168.             [shelfWindow display];
  169.     }
  170.     else
  171.         [shelfDisabledTee setEnabled:NO];
  172.  
  173.     [progressView setRatio:1.0];
  174.  
  175.     if (dgridValue)
  176.         iconRect.size.width = iconRect.size.height = dgridValue;
  177.     dockWindow = [[Window allocFromZone:NXCreateZone(vm_page_size, vm_page_size, YES)]
  178.                             initContent:&iconRect
  179.                                   style:NX_TOKENSTYLE
  180.                                 backing:NX_BUFFERED buttonMask:0 defer:NO];
  181.  
  182.     [dockWindow useOptimizedDrawing:YES];
  183.     [dockWindow addToEventMask:(NX_KEYDOWNMASK | NX_KEYUPMASK)];
  184.     [dockWindow setAvoidsActivation:YES];
  185.  
  186.     [dockWindow setFrameUsingName:"DockWindow"];
  187.     sprintf(string, "DockWindow%d-%d", (int)NX_WIDTH(&screenRect), (int)NX_HEIGHT(&screenRect));
  188.     [dockWindow setFrameUsingName:string];
  189.     [dockWindow getFrame:&contentRect];
  190.     if (NX_MIDX(&contentRect) > NX_WIDTH(&screenRect))
  191.         NX_X(&contentRect) = fmod(NX_X(&contentRect), NX_WIDTH(&screenRect)-NX_WIDTH(&contentRect));
  192.     if (NX_MIDY(&contentRect) > NX_HEIGHT(&screenRect))
  193.         NX_Y(&contentRect) = fmod(NX_Y(&contentRect), NX_HEIGHT(&screenRect)-NX_HEIGHT(&contentRect));
  194.     [dockWindow moveTo:NX_X(&contentRect) :NX_Y(&contentRect)];
  195.     [[dockWindow contentView] getFrame:&contentRect];
  196.  
  197.     if (showProgress)    {
  198.         [[progressField setStringValue:PROG_DOCK] display];
  199.         [progressView setRatio:0.0];
  200.     }
  201.     dockMgrView = [DockMgrView allocFromZone:[dockWindow zone]];
  202.     [IconView resetCachedDockImages];
  203.     [IconView setCachedDockImageSize:&contentRect.size];
  204.     [dockMgrView initFrame:&contentRect withWindow:dockWindow];
  205.     [dockMgrView startScanTimer];
  206.  
  207.     PSsetwindowlevel((sinkDock) ? lowerLevel : upperLevel, [dockWindow windowNum]);
  208.     [dockWindow setDelegate:dockMgrView];
  209.     [dockWindow display];
  210.     [dockWindow orderFront:self];
  211.  
  212.     if (backSpaceEnabled)    {
  213.         if (showProgress)    {
  214.             [[progressField setStringValue:PROG_BSPACE] display];
  215.             [progressView setRatio:0.0];
  216.         }
  217.         [NXApp loadNibSection:"BackSpace.nib" owner:self withNames:NO];
  218.         [thinker appDidInit:sender];
  219.         [progressView setRatio:1.0];
  220.     }
  221.     else
  222.         [backSpaceMenuItem setEnabled:NO];
  223.  
  224.     if (showProgress)
  225.         [progressPanel orderOut:self];
  226.  
  227.     sprintf(string, "%s/.AppInfo", NXHomeDirectory());
  228.     mkdir(string, 0777);
  229.     sprintf(string, "%s/.AppInfo/Fiend", NXHomeDirectory());
  230.     mkdir(string, 0777);
  231.  
  232.     sprintf(string, "%s", [(NXBundle *)[NXBundle mainBundle] directory]);
  233.     if (!onNeXTDock((const char *)string, screens[0].screenBounds.size.height))
  234.         [[[NXApp appIcon] getFrame:&origFrame] moveTo:-1000.0 :-1000.0];
  235.  
  236.     [self updateMenus];
  237.     [[Application workspace] beginListeningForApplicationStatusChanges];
  238.     [self perform:@selector(delayedAutolaunch) with:nil afterDelay:preLaunchDelay
  239.         cancelPrevious:NO];
  240.     return self;
  241. }
  242.  
  243. - appDidInit:sender
  244. {
  245.     [self perform:@selector(delayedAppDidInit:) with:sender afterDelay:1.0
  246.      cancelPrevious:NO];
  247.     return self;
  248. }
  249.  
  250. - updateMenus
  251. {
  252.     int        dockLevelCount = [dockMgrView levelCount];
  253.     int        dockSelCount = [dockMgrView hasSelectedCells];
  254.     int        stickySelCount = [[dockMgrView stickyDock] hasSelectedCells];
  255.     int        dockTotIconCount = [dockMgrView totalIconCount];
  256.     int        curDockIconCount = [[dockMgrView currentDock] iconCount];
  257.     int        shelfSelCount = (shelfView != nil) ? [shelfView hasSelectedCells] : 0;
  258.     int        shelfIconCount = (shelfView != nil) ? [[shelfView subviews] count] : 0;
  259.  
  260.     [dockLevelCountTee lazySetEnabled:(dockLevelCount > 1)];
  261.     [dockIconCountTee lazySetEnabled:(curDockIconCount > 0)];
  262.  
  263.     if (shelfView)    {
  264.         [shelfIconCountTee lazySetEnabled:(shelfIconCount > 0)];
  265.         [shelfSnapMenuItem lazySetEnabled:(shelfSelCount > 0)];
  266.     }
  267.  
  268.     [cutMenuItem lazySetEnabled:(shelfSelCount > 0 || (dockSelCount > 0 && stickySelCount == 0))];
  269.     [copyMenuItem lazySetEnabled:(shelfSelCount > 0 || dockSelCount > 0)];
  270.     [dockInspectMenuItem lazySetEnabled:(dockSelCount == 1 || stickySelCount == 1)];
  271.     [dockFindIconMenuItem lazySetEnabled:(dockTotIconCount > 0)];
  272.     [dockMoveIconsMenuItem lazySetEnabled:(dockSelCount > 0 && dockLevelCount > 1 && stickySelCount == 0)];
  273.     [dockAddWSMenuItem lazySetEnabled:([dockMgrView findLevelContaining:WKSPC_FILE switch:NO] == -1)];
  274.  
  275.     return self;
  276. }
  277.  
  278. - setProgressViewRatio:(float)aValue
  279. {
  280.     [progressView setRatio:aValue];
  281.     return self;
  282. }
  283.  
  284. - setProgressFieldString:(const char *)aString
  285. {
  286.     [[progressField setStringValue:aString] display];
  287.     return self;
  288. }
  289.  
  290. - hideOrShowMenus:sender
  291. {
  292.     [[MiscExplodingMenu sharedInstance] explodeMenus:sender];
  293.     return self;
  294. }
  295.  
  296. - appDidResignActive:sender
  297. {
  298.     [[dockMgrView window] endEditingFor:nil];
  299.     return self;
  300. }
  301.  
  302. - appDidHide:sender
  303. {
  304.     if (thinker != nil)
  305.         return [thinker appDidHide:sender];
  306.     else
  307.         return self;
  308. }
  309.  
  310. - appDidUnhide:sender
  311. {
  312.     if (thinker != nil)
  313.         return [thinker appDidUnhide:sender];
  314.     else
  315.         return self;
  316. }
  317.  
  318. - app:theApp applicationDidTerminate:(const char *)appName
  319. {
  320.     [dockMgrView app:theApp applicationDidTerminate:appName];
  321.     return self;
  322. }
  323.  
  324. - app:theApp applicationDidLaunch:(const char *)appName
  325. {
  326.     [dockMgrView app:theApp applicationDidLaunch:appName];
  327.     return self;
  328. }
  329.  
  330. - app:theApp applicationWillLaunch:(const char *)appName
  331. {
  332.     [dockMgrView app:theApp applicationWillLaunch:appName];
  333.     return self;
  334. }
  335.  
  336. - app:sender powerOffIn:(int)ms andSave:(int)aFlag
  337. {
  338.     return [NXApp terminate:self];
  339. }
  340.  
  341. - appWillTerminate:sender
  342. {
  343.     int            i;
  344.     int            screenCount;
  345.     char        string[100];
  346.     NXScreen    *screens;
  347.     NXRect        contentRect = {{0.0, 0.0}, {0.0, 0.0}};
  348.     BOOL        shelfEnabled = !strcmp(NXGetDefaultValue([NXApp appName], ENAB_SHELF), "YES");
  349.  
  350.     [NXApp getScreens:&screens count:&screenCount];
  351.     for(i = 0; i < screenCount; i++)
  352.         NXUnionRect(&screens[i].screenBounds, &contentRect);
  353.  
  354.     [dockMgrView killLauncher];
  355.     [dockMgrView vanishDocks:NO];
  356.     PSshowcursor(); NXPing();
  357.  
  358.     sprintf(string, "DockWindow%d-%d", (int)NX_WIDTH(&contentRect), (int)NX_HEIGHT(&contentRect));
  359.     [[dockMgrView window] saveFrameUsingName:string];
  360.  
  361.     sprintf(string, "%d", [dockMgrView currentDockIndex]+1);
  362.     NXWriteDefault([NXApp appName], CUR_DOCK, string);
  363.  
  364.     if (thinker != nil)
  365.         [thinker normalMode];
  366.  
  367.     if (shelfEnabled)
  368.         [shelfView writeShelf];
  369.     [dockMgrView writeDocks];
  370.     NXWriteDefault([NXApp appName], SHOW_DOCK, ([dockMgrView showDock])?"YES":"NO");
  371.     NXWriteDefault([NXApp appName], DOCK_LOCKED, ([dockMgrView dockLocked])?"YES":"NO");
  372.     PSshowcursor(); NXPing();
  373.  
  374.     return self;
  375. }
  376.  
  377. - applicationDefined:(NXEvent *)e
  378. {
  379.     if (thinker != nil)
  380.         return [thinker applicationDefined:e];
  381.     else
  382.         return self;
  383. }
  384.  
  385. - doPanel:(id *)panel named:(const char *) name
  386. {
  387.     char    path[MAXPATHLEN+1];
  388.     id        bundle = [NXBundle mainBundle];
  389.  
  390.     if ((*panel == nil) && [bundle getPath:path forResource:name ofType:"nib"])    {
  391.         [NXApp loadNibFile:path owner:self withNames:NO fromZone:[self zone]];
  392.         [*panel center];
  393.     }
  394.     [*panel makeKeyAndOrderFront:self];
  395.  
  396.     return self;
  397. }
  398.  
  399. - doDocument:sender
  400. {
  401.     char    path[MAXPATHLEN+1];
  402.     int        index = [[sender selectedCell] tag];
  403.     static char    *docs[] = {"aa_README.rtf",
  404.                            "ab_FAQ.rtf",
  405.                            "ac_ReleaseNotes.rtf",
  406.                            "ad_Instructions.rtfd"};
  407.  
  408.     sprintf(path, "%s/English.lproj/%s", [(NXBundle *)[NXBundle mainBundle] directory], docs[index]);
  409.     [[Application workspace] openFile:path];
  410.     return self;
  411. }
  412.  
  413. - doInfo:sender
  414. {
  415.     return [self doPanel:&infoPanel named:"Info"];
  416. }
  417.  
  418. - showBackSpaceSettings:sender
  419. {
  420.     [thinker showSettingsPanel:self];
  421.     [dockMgrView windowDidResignKey:self];
  422.     return self;
  423. }
  424.  
  425. - doBackSpaceScreenSaver:sender
  426. {
  427.     [thinker showFakeScreenSaver:self];
  428.     [dockMgrView windowDidResignKey:self];
  429.     return self;
  430. }
  431.  
  432. - whirl:sender
  433. {
  434.     NXSize        aSize;
  435.  
  436.     [NXApp getScreenSize:&aSize];
  437.     [dockMgrView stopScanTimer];
  438.     thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, 1000);
  439.     PSWSetDockOnTop(YES);
  440.     PSWWhirl(aSize.width/2.0, aSize.height/2.0);
  441.     PSWSetDockOnTop(NO);
  442.     [dockMgrView startScanTimer];
  443.     return self;
  444. }
  445.  
  446. - revertPreferences:sender
  447. {
  448.     const char    *appName = [NXApp appName];
  449.     int        sgridValue = atoi(NXGetDefaultValue(appName, SGRID_VALUE));
  450.     int        dgridValue = atoi(NXGetDefaultValue(appName, DGRID_VALUE));
  451.     double    scanTime = atof(NXGetDefaultValue(appName, SCAN_TIME));
  452.     BOOL    sgridEnabled = !strcmp(NXGetDefaultValue(appName, GRID_ENABLE), "YES");
  453.     BOOL    useSound = !strcmp(NXGetDefaultValue(appName, USE_SOUND), "YES");
  454.     BOOL    tileImage = !strcmp(NXGetDefaultValue(appName, TILE_IMAGE), "YES");
  455.     BOOL    sizeFont = !strcmp(NXGetDefaultValue(appName, SIZE_FONT), "YES");
  456.     BOOL    hideIcons = !strcmp(NXGetDefaultValue(appName, HIDE_ICONS), "YES");
  457.     BOOL    showSelPanel = !strcmp(NXGetDefaultValue(appName, SHOW_SELPNL), "YES");
  458.     BOOL    showProgress = !strcmp(NXGetDefaultValue(appName, SHOW_PROG), "YES");
  459.     BOOL    showDockIndex = !strcmp(NXGetDefaultValue(appName, SHOW_DCKIDX), "YES");
  460.     BOOL    enableDockClick = !strcmp(NXGetDefaultValue(appName, ENAB_DCLCK), "YES");
  461.     BOOL    enableShelfClick = !strcmp(NXGetDefaultValue(appName, ENAB_SCLCK), "YES");
  462.     BOOL    followLevels = !strcmp(NXGetDefaultValue(appName, FOLLOW_LEVS), "YES");
  463.     BOOL    enableBackSpace = !strcmp(NXGetDefaultValue(appName, ENAB_BSPACE), "YES");
  464.     BOOL    enableShelf = !strcmp(NXGetDefaultValue(appName, ENAB_SHELF), "YES");
  465.     BOOL    drawThumbnails = !strcmp(NXGetDefaultValue(appName, DRAW_TNAIL), "YES");
  466.     BOOL    limitShelfDepth = !strcmp(NXGetDefaultValue(appName, LIMIT_SHLF), "YES");
  467.     BOOL    dockStrictCopy = !strcmp(NXGetDefaultValue(appName, DSTRICT_COPY), "YES");
  468.     BOOL    shelfStrictCopy = !strcmp(NXGetDefaultValue(appName, SSTRICT_COPY), "YES");
  469.     BOOL    shelfAppTiles = !strcmp(NXGetDefaultValue(appName, SHELF_APPTIL), "YES");
  470.     BOOL    closePostLaunch = !strcmp(NXGetDefaultValue(appName, CLOSE_PSTLNCH), "YES");
  471.     BOOL    showCues = !strcmp(NXGetDefaultValue(appName, SHOW_CUES), "YES");
  472.     const char    *imageName = NXGetDefaultValue(appName, IMAGE_NAME);
  473.  
  474.     [shelfSizeField setIntValue:sgridValue];
  475.     [dockSizeField setIntValue:dgridValue];
  476.     if (scanTime >= 0.25 && scanTime <= 10.0)    {
  477.         [scanTimeField setFloatValue:scanTime];
  478.         [scanTimeSlider setFloatValue:scanTime];
  479.     }
  480.     else    {
  481.         [scanTimeField setStringValueNoProcess:"Off"];
  482.         [scanTimeSlider setFloatValue:[(Slider *)scanTimeSlider maxValue]];
  483.     }
  484.  
  485.     [useGridSwitch setState:sgridEnabled];
  486.     [useSoundSwitch setState:useSound];
  487.     [tileSwitch setState:tileImage];
  488.     [sizeFontSwitch setState:sizeFont];
  489.     [hideIconsSwitch setState:hideIcons];
  490.     [showSelPanelSwitch setState:showSelPanel];
  491.     [showProgressSwitch setState:showProgress];
  492.     [showIndexSwitch setState:showDockIndex];
  493.     [dockSingleClickSwitch setState:enableDockClick];
  494.     [shelfSingleClickSwitch setState:enableShelfClick];
  495.     [followLevelSwitch setState:followLevels];
  496.     [enableBackSpaceSwitch setState:enableBackSpace];
  497.     [enableShelfSwitch setState:enableShelf];
  498.     [drawThumbnailSwitch setState:drawThumbnails];
  499.     [limitDepthSwitch setState:limitShelfDepth];
  500.     [dockStrictCopySwitch setState:dockStrictCopy];
  501.     [shelfStrictCopySwitch setState:shelfStrictCopy];
  502.     [showAppTileSwitch setState:shelfAppTiles];
  503.     [closePostLaunchSwitch setState:closePostLaunch];
  504.     [showCuesSwitch setState:showCues];
  505.     [imageFileField setStringValue:imageName];
  506.  
  507.     if (!enableShelf)
  508.         [shelfDisabledPrefsTee setEnabled:NO];
  509.  
  510.     [setPrefsButton setEnabled:NO];
  511.     [revertPrefsButton setEnabled:NO];
  512.  
  513.     return self;
  514. }
  515.  
  516.  
  517. - setPreferences:sender
  518. {
  519.     const char    *appName = [NXApp appName];
  520.     int        sGridValue = [shelfSizeField intValue];
  521.     int        dGridValue = [dockSizeField intValue];
  522.     float    scanTime = [scanTimeSlider floatValue];
  523.     BOOL    sgridEnabled = [useGridSwitch state];
  524.     BOOL    useSound = [useSoundSwitch state];
  525.     BOOL    tileImage = [tileSwitch state];
  526.     BOOL    sizeFont = [sizeFontSwitch state];
  527.     BOOL    hideIcons = [hideIconsSwitch state];
  528.     BOOL    showSelPanel = [showSelPanelSwitch state];
  529.     BOOL    showProgress = [showProgressSwitch state];
  530.     BOOL    showDockIndex = [showIndexSwitch state];
  531.     BOOL    enableDockClick = [dockSingleClickSwitch state];
  532.     BOOL    enableShelfClick = [shelfSingleClickSwitch state];
  533.     BOOL    followLevels = [followLevelSwitch state];
  534.     BOOL    enableBackSpace = [enableBackSpaceSwitch state];
  535.     BOOL    enableShelf = [enableShelfSwitch state];
  536.     BOOL    drawThumbnails = [drawThumbnailSwitch state];
  537.     BOOL    limitShelfDepth = [limitDepthSwitch state];
  538.     BOOL    dockStrictCopy = [dockStrictCopySwitch state];
  539.     BOOL    shelfStrictCopy = [shelfStrictCopySwitch state];
  540.     BOOL    shelfAppTiles = [showAppTileSwitch state];
  541.     BOOL    closePostLaunch = [closePostLaunchSwitch state];
  542.     BOOL    showCues = [showCuesSwitch state];
  543.     const char    *imageName = [imageFileField stringValue];
  544.  
  545.     int        oldSGridValue = atoi(NXGetDefaultValue(appName, SGRID_VALUE));
  546.     int        oldDGridValue = atoi(NXGetDefaultValue(appName, DGRID_VALUE));
  547.     double    oldScanTime = atof(NXGetDefaultValue(appName, SCAN_TIME));
  548.     BOOL    oldSgridEnabled = !strcmp(NXGetDefaultValue(appName, GRID_ENABLE), "YES");
  549.     BOOL    oldUseSound = !strcmp(NXGetDefaultValue(appName, USE_SOUND), "YES");
  550.     BOOL    oldTileImage = !strcmp(NXGetDefaultValue(appName, TILE_IMAGE), "YES");
  551.     BOOL    oldSizeFont = !strcmp(NXGetDefaultValue(appName, SIZE_FONT), "YES");
  552.     BOOL    oldHideIcons = !strcmp(NXGetDefaultValue(appName, HIDE_ICONS), "YES");
  553.     BOOL    oldShowSelPanel = !strcmp(NXGetDefaultValue(appName, SHOW_SELPNL), "YES");
  554.     BOOL    oldShowProgress = !strcmp(NXGetDefaultValue(appName, SHOW_PROG), "YES");
  555.     BOOL    oldShowDockIndex = !strcmp(NXGetDefaultValue(appName, SHOW_DCKIDX), "YES");
  556.     BOOL    oldEnableDockClick = !strcmp(NXGetDefaultValue(appName, ENAB_DCLCK), "YES");
  557.     BOOL    oldEnableShelfClick = !strcmp(NXGetDefaultValue(appName, ENAB_SCLCK), "YES");
  558.     BOOL    oldFollowLevels = !strcmp(NXGetDefaultValue(appName, FOLLOW_LEVS), "YES");
  559.     BOOL    oldEnableBackSpace = !strcmp(NXGetDefaultValue(appName, ENAB_BSPACE), "YES");
  560.     BOOL    oldEnableShelf = !strcmp(NXGetDefaultValue(appName, ENAB_SHELF), "YES");
  561.     BOOL    oldDrawThumbnails = !strcmp(NXGetDefaultValue(appName, DRAW_TNAIL), "YES");
  562.     BOOL    oldLimitShelfDepth = !strcmp(NXGetDefaultValue(appName, LIMIT_SHLF), "YES");
  563.     BOOL    oldDockStrictCopy = !strcmp(NXGetDefaultValue(appName, DSTRICT_COPY), "YES");
  564.     BOOL    oldShelfStrictCopy = !strcmp(NXGetDefaultValue(appName, SSTRICT_COPY), "YES");
  565.     BOOL    oldShelfAppTiles = !strcmp(NXGetDefaultValue(appName, SHELF_APPTIL), "YES");
  566.     BOOL    oldClosePostLaunch = !strcmp(NXGetDefaultValue(appName, CLOSE_PSTLNCH), "YES");
  567.     BOOL    oldShowCues = !strcmp(NXGetDefaultValue(appName, SHOW_CUES), "YES");
  568.     const char    *oldImageName = NXGetDefaultValue(appName, IMAGE_NAME);
  569.  
  570.     if (dGridValue != oldDGridValue)    {
  571.         NXWriteDefault(appName, DGRID_VALUE, [dockSizeField stringValue]);
  572.         [dockMgrView setIconSize:[dockSizeField intValue]];
  573.     }
  574.  
  575.     if (sGridValue != oldSGridValue)    {
  576.         NXWriteDefault(appName, SGRID_VALUE, [shelfSizeField stringValue]);
  577.         [shelfView setAutodisplay:NO];
  578.         [shelfView setGridValue:[shelfSizeField intValue]];
  579.     }
  580.  
  581.     if (scanTime != oldScanTime)    {
  582.         if (scanTime > 10.0)    {
  583.             scanTime = -1.0;
  584.             NXWriteDefault(appName, SCAN_TIME, "-1.0");
  585.             [dockMgrView restoreIcons];
  586.         }
  587.         else
  588.             NXWriteDefault(appName, SCAN_TIME, [scanTimeSlider stringValue]);
  589.         [dockMgrView stopScanTimer];
  590.         [dockMgrView startScanTimer];
  591.     }
  592.  
  593.     if (sgridEnabled != oldSgridEnabled)
  594.         NXWriteDefault(appName, GRID_ENABLE, (sgridEnabled)?"YES":"NO");
  595.  
  596.     if (useSound != oldUseSound)
  597.         NXWriteDefault(appName, USE_SOUND, (useSound)?"YES":"NO");
  598.  
  599.     if (strcmp(imageName, oldImageName))    {
  600.         [shelfView setAutodisplay:NO];
  601.         if ([shelfView setImageFileName:[imageFileField stringValue]])
  602.             NXWriteDefault(appName, IMAGE_NAME, imageName);
  603.         else
  604.             [imageFileField setStringValue:oldImageName];
  605.     }
  606.  
  607.     if (tileImage != oldTileImage)    {
  608.         NXWriteDefault(appName, TILE_IMAGE, (tileImage)?"YES":"NO");
  609.         [shelfView setAutodisplay:NO];
  610.         [shelfView setTileImage:tileImage];
  611.     }
  612.  
  613.     if (sizeFont != oldSizeFont)
  614.         NXWriteDefault(appName, SIZE_FONT, (sizeFont)?"YES":"NO");
  615.  
  616.     if (hideIcons != oldHideIcons)    {
  617.         NXWriteDefault(appName, HIDE_ICONS, (hideIcons)?"YES":"NO");
  618.         [dockMgrView vanishDocks:hideIcons];
  619.     }
  620.  
  621.     if (showSelPanel != oldShowSelPanel)
  622.         NXWriteDefault(appName, SHOW_SELPNL, (showSelPanel)?"YES":"NO");
  623.     if (showProgress != oldShowProgress)
  624.         NXWriteDefault(appName, SHOW_PROG, (showProgress)?"YES":"NO");
  625.     if (showDockIndex != oldShowDockIndex)
  626.         NXWriteDefault(appName, SHOW_DCKIDX, (showDockIndex)?"YES":"NO");
  627.     if (enableDockClick != oldEnableDockClick)
  628.         NXWriteDefault(appName, ENAB_DCLCK, (enableDockClick)?"YES":"NO");
  629.     if (enableShelfClick != oldEnableShelfClick)
  630.         NXWriteDefault(appName, ENAB_SCLCK, (enableShelfClick)?"YES":"NO");
  631.     if (followLevels != oldFollowLevels)    {
  632.         NXWriteDefault(appName, FOLLOW_LEVS, (followLevels)?"YES":"NO");
  633.         [dockMgrView setFollowLevels:followLevels];
  634.     }
  635.     if (enableBackSpace != oldEnableBackSpace)
  636.         NXWriteDefault(appName, ENAB_BSPACE, (enableBackSpace)?"YES":"NO");
  637.     if (enableShelf != oldEnableShelf)
  638.         NXWriteDefault(appName, ENAB_SHELF, (enableShelf)?"YES":"NO");
  639.     if (drawThumbnails != oldDrawThumbnails)
  640.         NXWriteDefault(appName, DRAW_TNAIL, (drawThumbnails)?"YES":"NO");
  641.     if (limitShelfDepth != oldLimitShelfDepth)
  642.         NXWriteDefault(appName, LIMIT_SHLF, (limitShelfDepth)?"YES":"NO");
  643.     if (dockStrictCopy != oldDockStrictCopy)
  644.         NXWriteDefault(appName, DSTRICT_COPY, (dockStrictCopy)?"YES":"NO");
  645.     if (shelfStrictCopy != oldShelfStrictCopy)
  646.         NXWriteDefault(appName, SSTRICT_COPY, (shelfStrictCopy)?"YES":"NO");
  647.     if (shelfAppTiles != oldShelfAppTiles)
  648.         NXWriteDefault(appName, SHELF_APPTIL, (shelfAppTiles)?"YES":"NO");
  649.     if (closePostLaunch != oldClosePostLaunch)
  650.         NXWriteDefault(appName, CLOSE_PSTLNCH, (closePostLaunch)?"YES":"NO");
  651.     if (showCues != oldShowCues)    {
  652.         NXWriteDefault(appName, SHOW_CUES, (showCues)?"YES":"NO");
  653.         [dockMgrView redisplayAllIcons];
  654.     }
  655.  
  656.     [shelfView displayIfNeeded];
  657.     [dockMgrView display];
  658.  
  659.     [setPrefsButton setEnabled:NO];
  660.     [revertPrefsButton setEnabled:NO];
  661.  
  662.     return self;
  663. }
  664.  
  665. - doPreferences:sender
  666. {
  667.  
  668.     [self doPanel:&prefPanel named:"Preferences"];
  669.     [prefPanel disableFlushWindow];
  670.     [self revertPreferences:self];
  671.     [[prefPanel reenableFlushWindow] flushWindowIfNeeded];
  672.     [dockMgrView windowDidResignKey:self];
  673.  
  674.     return self;
  675. }
  676.  
  677. - activatePrefButtons:sender
  678. {
  679.     if (sender != self && [sender tag] == 1)    {
  680.         NXRunAlertPanel([NXApp appName],
  681.                         "This change will take effect when you restart Fiend...",
  682.                         NULL, NULL, NULL);
  683.     }
  684.  
  685.     [setPrefsButton setEnabled:YES];
  686.     [revertPrefsButton setEnabled:YES];
  687.     return self;
  688. }
  689.  
  690. - takeFloatValueFrom:sender
  691. {
  692.     float    value = [sender floatValue];
  693.  
  694.     if (value > 10.0)    {
  695.         [scanTimeSlider setFloatValue:[(Slider *)scanTimeSlider maxValue]];
  696.         [scanTimeField setStringValueNoProcess:"Off"];
  697.     }
  698.     else    {
  699.         if (sender == scanTimeSlider)
  700.             [scanTimeField setFloatValue:[sender floatValue]];
  701.         else    {
  702.             [sender selectText:self];
  703.             [scanTimeSlider setFloatValue:[sender floatValue]];
  704.         }
  705.     }
  706.     return [self activatePrefButtons:self];
  707. }
  708.  
  709. - textDidChange:sender
  710. {
  711.     return [self activatePrefButtons:self];
  712. }
  713.  
  714. - setBackSpacePassword:sender;
  715. {
  716.     if (thinker != nil)
  717.         [passObj setPassword:sender];
  718.     return self;
  719. }
  720.  
  721. - ping:sender
  722. {
  723.     return [self activatePrefButtons:self];
  724. }
  725.  
  726. - clearLevel:sender
  727. {
  728.     [dockMgrView clearDockLevel];
  729.     return self;
  730. }
  731.  
  732. - rotateLevel:sender
  733. {
  734.     [dockMgrView rotateOffsets];
  735.     [dockMgrView display];
  736.     return self;
  737. }
  738.  
  739. - toggleDockLock:sender
  740. {
  741.     [dockMgrView setDockLocked:![dockMgrView dockLocked]];
  742.     return self;
  743. }
  744.  
  745. - toggleDock:sender
  746. {
  747.     [dockMgrView setShowDock:![dockMgrView showDock]];
  748.     return self;
  749. }
  750.  
  751. - nextLevel:sender
  752. {
  753.     [dockMgrView nextLevel];
  754.     return self;
  755. }
  756.  
  757. - previousLevel:sender
  758. {
  759.     [dockMgrView previousLevel];
  760.     return self;
  761. }
  762.  
  763. - nameLevel:sender
  764. {
  765.     [nameLevelField setStringValue:[[dockMgrView currentDock] name]];
  766.     [nameLevelField selectText:self];
  767.     [dockMgrView windowDidResignKey:self];
  768.     modalCanceled = NO;
  769.     [NXApp runModalFor:nameLevelPanel];
  770.     if (!modalCanceled)    {
  771.         [(DockMgrView *)dockMgrView nameLevel:(char *)[nameLevelField stringValue]];
  772.         [dockMgrView display];
  773.     }
  774.  
  775.     return self;
  776. }
  777.  
  778. - findNamedLevel:sender
  779. {
  780.     [findLevelStringField selectText:self];
  781.     [dockMgrView windowDidResignKey:self];
  782.     modalCanceled = NO;
  783.     [NXApp runModalFor:findLevelPanel];
  784.     if (!modalCanceled)    {
  785.         [dockMgrView gotoNamedLevel:(char *)[findLevelStringField stringValue]];
  786.         [dockMgrView display];
  787.     }
  788.     return self;
  789. }
  790.  
  791. - moveIcons:sender
  792. {
  793.     [moveIconsField selectText:self];
  794.     [dockMgrView windowDidResignKey:self];
  795.     modalCanceled = NO;
  796.     [NXApp runModalFor:moveIconsPanel];
  797.     if (!modalCanceled)   {
  798.         [dockMgrView moveIconsTo:[moveIconsField intValue]-1];
  799.         [dockMgrView display];
  800.     }
  801.     return self;
  802. }
  803.  
  804. - gotoLevel:sender
  805. {
  806.     [gotoField setIntValue:[dockMgrView currentDockIndex]+1];
  807.     [gotoField selectText:self];
  808.     [dockMgrView windowDidResignKey:self];
  809.     modalCanceled = NO;
  810.     [NXApp runModalFor:gotoPanel];
  811.     if (!modalCanceled)   {
  812.         [dockMgrView gotoDockLevel:[gotoField intValue]-1];
  813.         [dockMgrView display];
  814.     }
  815.     return self;
  816. }
  817.  
  818. - moveLevel:sender
  819. {
  820.     [moveField setIntValue:[dockMgrView currentDockIndex]+1];
  821.     [moveField selectText:self];
  822.     [dockMgrView windowDidResignKey:self];
  823.     modalCanceled = NO;
  824.     [NXApp runModalFor:movePanel];
  825.     if (!modalCanceled)  {
  826.         [dockMgrView moveLevelTo:[moveField intValue]-1];
  827.         [dockMgrView display];
  828.     }
  829.     return self;
  830. }
  831.  
  832. - sendLevelToBottom:sender
  833. {
  834.     [(DockMgrView *)dockMgrView sendCurrentToBottom];
  835.     [dockMgrView display];
  836.     return self;
  837. }
  838.  
  839. - bringLevelToTop:sender
  840. {
  841.     [(DockMgrView *)dockMgrView bringCurrentToTop];
  842.     [dockMgrView display];
  843.     return self;
  844. }
  845.  
  846. - findNamedIcon:sender
  847. {
  848.     [findIconStringField selectText:self];
  849.     [dockMgrView windowDidResignKey:self];
  850.     modalCanceled = NO;
  851.     [NXApp runModalFor:findIconPanel];
  852.     if (!modalCanceled)  {
  853.         [dockMgrView findLevelContaining:[findIconStringField stringValue] switch:YES];
  854.         [dockMgrView display];
  855.     }
  856.     return self;
  857. }
  858.  
  859. - inspectIcon:sender
  860. {
  861.     [dockMgrView inspectIcon:self];
  862.     return self;
  863. }
  864.  
  865. - addLevel:sender
  866. {
  867.     [dockMgrView addLevel];
  868.     [dockMgrView display];
  869.     return self;
  870. }
  871.  
  872. - deleteLevel:sender
  873. {
  874.     [dockMgrView deleteLevel];
  875.     [dockMgrView display];
  876.     return self;
  877. }
  878.  
  879. - modalDone:sender
  880. {
  881.     [[sender window] orderOut:self];
  882.     [NXApp stopModal];
  883.     if ([sender tag] == 0)
  884.         modalCanceled = YES;
  885.     return self;
  886. }
  887.  
  888. - windowWillClose:sender
  889. {
  890.     if (sender == infoPanel) infoPanel = nil;
  891.     if (sender == prefPanel) prefPanel = nil;
  892.     return self;
  893. }
  894.  
  895.  
  896. - setShelfImage:sender
  897. {
  898.     id    openPanel = [OpenPanel new];
  899.     const char * const *types = [NXImage imageFileTypes];
  900.  
  901.     if (![openPanel runModalForDirectory:"." file:"" types:types])
  902.         return nil;
  903.     [imageFileField setStringValue:[openPanel filename]];
  904.     [imageFileField selectText:self];
  905.     [self activatePrefButtons:self];
  906.     return self;
  907. }
  908.  
  909. - snapShelfToGrid:sender
  910. {
  911.     if ([shelfView hasSelectedCells])
  912.         [shelfView alignSubviews];
  913.     return self;
  914. }
  915.  
  916. - selectShelf:sender
  917. {
  918.     NXRect        frame;
  919.  
  920.     [shelfView getFrame:&frame];
  921.     NXInsetRect(&frame, -1000.0, -1000.0);
  922.     [shelfView selectViewsInRect:&frame deselect:YES];
  923.     [self updateMenus];
  924.     return self;
  925. }
  926.  
  927. - selectDock:sender
  928. {
  929.     [[dockMgrView currentDock] select:YES all:self];
  930.     if (![dockMgrView showDock])
  931.         [dockMgrView setShowDock:YES];
  932.     [self updateMenus];
  933.     return self;
  934. }
  935.  
  936. - (NXZone *)dockZone
  937. {
  938.     return [dockMgrView zone];
  939. }
  940.  
  941. - (NXZone *)shelfZone
  942. {
  943.     return [shelfView zone];
  944. }
  945.  
  946. - deselectShelf
  947. {
  948.     [shelfView deselectAll:self];
  949.     return self;
  950. }
  951.  
  952. - deselectDock
  953. {
  954.     [dockMgrView deselectAll:self];
  955.     return self;
  956. }
  957.  
  958. - addWorkspaceToDock:sender
  959. {
  960.     [dockMgrView addWorkspace];
  961.     return self;
  962. }
  963.  
  964. - addRecyclerToDock:sender
  965. {
  966.     [dockMgrView addRecycler];
  967.     return self;
  968. }
  969.  
  970. - validRequestorForSendType:(NXAtom)typeSent andReturnType:(NXAtom)typeReturned
  971. {
  972.     if ((typeSent == NXFilenamePboardType || typeSent == NULL) && (typeReturned == NULL))    {
  973.         if (typeSent == NULL || [shelfView hasSelectedCells] || [dockMgrView hasSelectedCells])
  974.             return self;
  975.     }
  976.     else if ((typeReturned == NXFilenamePboardType) || (typeReturned == NXAsciiPboardType))
  977.         return self;
  978.     return nil;
  979. }
  980.  
  981. - submitToFiendDock:(id)pb userData:(const char *)data error:(char **)msg
  982. {
  983.     [dockMgrView paste:self toPasteboard:pb];
  984.     return self;
  985. }
  986.  
  987. - submitToFiendShelf:(id)pb userData:(const char *)data error:(char **)msg
  988. {
  989.     BOOL    shelfEnabled = !strcmp(NXGetDefaultValue([NXApp appName], ENAB_SHELF), "YES");
  990.  
  991.     if (shelfEnabled)
  992.         return [shelfView paste:self toPasteboard:pb];
  993.     else    {
  994.         NXRunAlertPanel([NXApp appName], "Fiend Shelf is not enabled!!", NULL, NULL, NULL);
  995.         return nil;
  996.     }
  997.     return self;
  998. }
  999.  
  1000. - (BOOL)writeSelectionToPasteboard:pb types:(NXAtom *)types
  1001. {
  1002.     BOOL    shelfEnabled = !strcmp(NXGetDefaultValue([NXApp appName], ENAB_SHELF), "YES");
  1003.  
  1004.     if (shelfEnabled && [shelfView hasSelectedCells])    {
  1005.         [shelfView copy:self toPasteboard:pb andCut:NO];
  1006.         [shelfView deselectAll:self];
  1007.     }
  1008.     else if ([dockMgrView hasSelectedCells])    {
  1009.         [dockMgrView copy:self toPasteboard:pb andCut:NO];
  1010.         [dockMgrView deselectAll:self];
  1011.     }
  1012.     else    {
  1013.         NXBeep();
  1014.         return NO;
  1015.     }
  1016.     return YES;
  1017. }
  1018.  
  1019. - copy:sender
  1020. {
  1021.     id        pb = [Pasteboard new];
  1022.     BOOL    shelfEnabled = !strcmp(NXGetDefaultValue([NXApp appName], ENAB_SHELF), "YES");
  1023.  
  1024.     if (shelfEnabled && [shelfView hasSelectedCells])
  1025.         [shelfView copy:self toPasteboard:pb andCut:NO];
  1026.     else if ([dockMgrView hasSelectedCells])
  1027.         [dockMgrView copy:self toPasteboard:pb andCut:NO];
  1028.     else    {
  1029.         NXBeep();
  1030.         return nil;
  1031.     }
  1032.     return self;
  1033. }
  1034.  
  1035.  
  1036. - cut:sender
  1037. {
  1038.     id        pb = [Pasteboard new];
  1039.     BOOL    shelfEnabled = !strcmp(NXGetDefaultValue([NXApp appName], ENAB_SHELF), "YES");
  1040.  
  1041.     if (shelfEnabled && [shelfView hasSelectedCells])
  1042.         [shelfView copy:self toPasteboard:pb andCut:YES];
  1043.     else if ([dockMgrView hasSelectedCells])
  1044.         [dockMgrView copy:self toPasteboard:pb andCut:YES];
  1045.     else
  1046.         NXBeep();
  1047.     return self;
  1048. }
  1049.  
  1050. - pasteToShelf:sender
  1051. {
  1052.     int        status;
  1053.     char     *showSelPanel = (char *)NXGetDefaultValue([NXApp appName], SHOW_SELPNL);
  1054.     BOOL    shelfEnabled = !strcmp(NXGetDefaultValue([NXApp appName], ENAB_SHELF), "YES");
  1055.  
  1056.     if (!shelfEnabled)    {
  1057.         NXRunAlertPanel([NXApp appName], "Fiend Shelf is not enabled!!", NULL, NULL, NULL);
  1058.         return nil;
  1059.     }
  1060.  
  1061.     if (!strcmp(showSelPanel, "YES"))    {
  1062.         status = NXRunAlertPanel([NXApp appName],
  1063.                                  "Click mouse to choose paste site...",
  1064.                                  "Ok", "Ok Forever", NULL);
  1065.         if (status == NX_ALERTALTERNATE)
  1066.             NXWriteDefault([NXApp appName], SHOW_SELPNL, "NO");
  1067.     }
  1068.  
  1069.     [shelfView deselectAll:self];
  1070.     [dockMgrView deselectAll:self];
  1071.     [shelfView paste:self];
  1072.  
  1073.     return self;
  1074. }
  1075.  
  1076. - pasteToDock:sender
  1077. {
  1078.     [shelfView deselectAll:self];
  1079.     [dockMgrView deselectAll:self];
  1080.     [dockMgrView paste:self];
  1081.  
  1082.     return self;
  1083. }
  1084.  
  1085. - doSuggestion:sender
  1086. {
  1087.     id        to = [MiscString newWithString:EMAIL_ADDRESS];
  1088.     id        subj = [[MiscString alloc] init];
  1089.     id        body = [[MiscString alloc] init];
  1090.     id        mailer = [MiscMailApp localMailer];
  1091.     struct passwd *pwdStruct = getpwuid(getuid());
  1092.  
  1093.     [body setFromFormat:"Hi Dave!\n\nGreat work on Fiend v%s - but I have to tell you...\n\n\n\n\n- %s\n",
  1094.                             FIEND_VERSION, pwdStruct->pw_gecos];
  1095.     [subj setFromFormat:"Suggestion/Bug Report for Fiend v%s", FIEND_VERSION];
  1096.     [mailer sendMailTo:to subject:subj body:body];
  1097.  
  1098.     [to free];
  1099.     [body free];
  1100.     [subj free];
  1101.     
  1102.     return self;
  1103.  
  1104. - (const char *)appDirectory
  1105. {
  1106.     return [thinker appDirectory];
  1107. }
  1108.  
  1109. - commonImageInspector
  1110. {
  1111.     return [thinker commonImageInspector];
  1112. }
  1113.  
  1114. - (struct mach_header *) headerForModule:(const char *)name
  1115. {
  1116.     return [thinker headerForModule:name];
  1117. }
  1118.  
  1119. - (const char *)moduleDirectory:(const char *)name
  1120. {
  1121.     return [thinker moduleDirectory:name];
  1122. }
  1123.  
  1124. - (NXDragOperation) draggingSourceOperationMaskForLocal:(BOOL)flag
  1125. {
  1126.     return NX_DragOperationAll;
  1127. }
  1128.  
  1129. @end
  1130.