home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / cdrom / compactplayer / source / indexeditor.c < prev    next >
C/C++ Source or Header  |  1995-12-28  |  20KB  |  818 lines

  1. /* CompactPlayer CD title editor, based on EnvEdit */
  2.  
  3. #include <exec/types.h>
  4. #include <exec/memory.h>
  5. #include <dos/exall.h>
  6. #include <intuition/intuition.h>
  7. #include <intuition/gadgetclass.h>
  8. #include <intuition/imageclass.h>
  9. #include <intuition/icclass.h>
  10. #include <utility/tagitem.h>
  11. #include <proto/dos.h>
  12. #include <proto/exec.h>
  13. #include <proto/icon.h>
  14. #include <proto/intuition.h>
  15. #include <classact.h>
  16. #include <strings.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19.  
  20. /* #define D(x) x to compile with debugging output.
  21.  */
  22. #define D(x)
  23.  
  24. #ifdef _DCC
  25. #define SAVEDS __geta4
  26. #define ASM
  27. #define REG_A0 __A0
  28. #define REG_A1 __A1
  29. #else
  30. #define SAVEDS __saveds
  31. #define ASM __asm
  32. #define REG_A0 register __a0
  33. #define REG_A1 register __a1
  34. #endif
  35.  
  36. enum { GAD_LIST = 1, GAD_EDIT, GAD_SAVE, GAD_DEL, GAD_CANCEL };
  37.  
  38. /* ARexx command IDs
  39.  */
  40. enum { REXX_NAME, REXX_VERSION, REXX_AUTHOR, REXX_ACTIVATE, REXX_DEACTIVATE,
  41.         REXX_QUIT, REXX_WINDOWTOBACK, REXX_WINDOWTOFRONT };
  42.  
  43.  
  44.  
  45. /* Some additional info we put in listbrowser node userdata field.
  46.  */
  47. struct LBUserData
  48. {
  49.     UBYTE lbud_FileName[255];
  50.     BOOL lbud_Changed;
  51.     BOOL lbud_Deleted;
  52.     STRPTR lbud_Buf;
  53.     ULONG lbud_BufSize;
  54. };
  55.  
  56.  
  57. /* Function prototypes.
  58.  */
  59. VOID load_text(struct Window *);
  60. LONG file_size(char *);
  61. VOID save_changed(struct List *, BOOL);
  62. BOOL read_files(struct List *, STRPTR, WORD);
  63. VOID bstrcpy(STRPTR, BSTR);
  64. VOID free_list(struct List *);
  65. LONG easy_req(struct Window *, char *, char *, char *, ...);
  66. VOID ASM rexx_name(REG_A0 struct ARexxCmd *, REG_A1 struct RexxMsg *);
  67. VOID ASM rexx_version(REG_A0 struct ARexxCmd *, REG_A1 struct RexxMsg *);
  68. VOID ASM rexx_author(REG_A0 struct ARexxCmd *, REG_A1 struct RexxMsg *);
  69. VOID ASM rexx_activate(REG_A0 struct ARexxCmd *, REG_A1 struct RexxMsg *);
  70. VOID ASM rexx_deactivate(REG_A0 struct ARexxCmd *, REG_A1 struct RexxMsg *);
  71. VOID ASM rexx_quit(REG_A0 struct ARexxCmd *, REG_A1 struct RexxMsg *);
  72. VOID ASM rexx_about(REG_A0 struct ARexxCmd *, REG_A1 struct RexxMsg *);
  73. VOID ASM rexx_windowtoback(REG_A0 struct ARexxCmd *, REG_A1 struct RexxMsg *);
  74. VOID ASM rexx_windowtofront(REG_A0 struct ARexxCmd *, REG_A1 struct RexxMsg *);
  75.  
  76. /* Global variables.
  77.  */
  78. struct List file_list;
  79. struct Gadget *layout, *list_gad, *edit_gad;
  80. struct DrawInfo *drinfo;
  81. Object *window_obj;
  82. struct Window *win;
  83. BOOL ok = TRUE;
  84.  
  85. struct ColumnInfo ci[] =
  86. {
  87.     { 40, "Artist", 0 },
  88.     { 40, "Record", 0 },
  89.     { 20, "ID", 0 },
  90.     { -1, (STRPTR)~0, -1 }
  91. };
  92.  
  93. /* ARexx command table.  These commands may not seem terribly useful at first,
  94.  * but these are a basic set of commands that every app should support.
  95.  */
  96. struct ARexxCmd arexx_cmds[] =
  97. {
  98.     { "NAME",            REXX_NAME,            rexx_name,            NULL,        NULL, },
  99.     { "VERSION",        REXX_VERSION,        rexx_version,        NULL,        NULL, },
  100.     { "AUTHOR",            REXX_AUTHOR,        rexx_author,        NULL,        NULL, },
  101.     { "ACTIVATE",        REXX_ACTIVATE,        rexx_activate,        NULL,        NULL, },
  102.     { "DEACTIVATE",        REXX_DEACTIVATE,    rexx_deactivate,    NULL,        NULL, },
  103.     { "QUIT",            REXX_QUIT,            rexx_quit,            NULL,        NULL, },
  104.     { "WINDOWTOBACK",    REXX_WINDOWTOBACK,    rexx_windowtoback,    NULL,        NULL, },
  105.     { "WINDOWTOFRONT",    REXX_WINDOWTOFRONT,    rexx_windowtofront,    NULL,        NULL, },
  106.     { NULL,                NULL,                NULL,                NULL,        NULL, }
  107. };
  108.  
  109.  
  110. /* This is the start of our programme.
  111.  */
  112. #ifdef _DCC
  113. wbmain() { main(); }
  114. #endif
  115.  
  116. int main(int ac, char **av)
  117. {
  118.     struct Screen *screen = NULL;
  119.  
  120.     if (!ButtonBase) return(20);
  121.  
  122.     /* We'll just open up on the default public screen, and use its screen font.
  123.      */
  124.     if (screen = LockPubScreen(NULL))
  125.     {
  126.         UWORD mapping[4];
  127.  
  128.         drinfo = GetScreenDrawInfo(screen);
  129.  
  130.         NewList(&file_list);
  131.         read_files(&file_list, ac > 1 ? av[1] : "Disks", 1);
  132.  
  133.         /* Setup a simple mapping.
  134.          */
  135.         mapping[0] = drinfo->dri_Pens[BACKGROUNDPEN];
  136.         mapping[1] = drinfo->dri_Pens[SHADOWPEN];
  137.         mapping[2] = drinfo->dri_Pens[SHINEPEN];
  138.         mapping[3] = drinfo->dri_Pens[FILLPEN];
  139.  
  140.         /* Do the layout.
  141.          */
  142.         if (layout = LayoutObject,
  143.                             GA_DrawInfo, drinfo,
  144.                             ICA_TARGET, ICTARGET_IDCMP,
  145.                             LAYOUT_DeferLayout, TRUE,
  146.  
  147.                             LAYOUT_SpaceOuter, TRUE,
  148.                             LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
  149.                             LAYOUT_HorizAlignment, LAYOUT_ALIGN_CENTER,
  150.  
  151.                             LAYOUT_AddChild, list_gad = ListBrowserObject,
  152.                                 GA_ID, GAD_LIST,
  153.                                 GA_RelVerify, TRUE,
  154.                                 LISTBROWSER_Labels, (ULONG)&file_list,
  155.                                 LISTBROWSER_ColumnInfo, (ULONG)&ci,
  156.                                 LISTBROWSER_ColumnTitles, TRUE,
  157.                                 LISTBROWSER_ShowSelected, TRUE,
  158.                                 LISTBROWSER_Separators, FALSE,
  159.                                 LISTBROWSER_Hierarchical, TRUE,
  160.                                 LISTBROWSER_AutoFit, TRUE,
  161.                                 ListBrowserEnd,
  162.                             CHILD_WeightedHeight, 100,
  163.  
  164.                             LAYOUT_AddChild, edit_gad = TextFieldObject,
  165.                                 GA_ID, GAD_EDIT,
  166.                                 GA_RelVerify, TRUE,
  167.                                 TEXTFIELD_Border, TEXTFIELD_BORDER_DOUBLEBEVEL,
  168.                                 TextFieldEnd,
  169.                             CHILD_MinHeight, screen->Font->ta_YSize + 6,
  170.                             CHILD_WeightedHeight, 50,
  171.  
  172.                             LAYOUT_AddChild, LayoutObject,
  173.                                 LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
  174.                                 LAYOUT_EvenSize, TRUE,
  175.     
  176.                                 LAYOUT_AddChild, ButtonObject,
  177.                                     GA_ID, GAD_SAVE,
  178.                                     GA_Text, "_Save",
  179.                                     GA_RelVerify, TRUE,
  180.                                     ButtonEnd,
  181.                                 CHILD_NominalSize, TRUE,
  182.                                 CHILD_WeightedWidth, 0,
  183.  
  184.                                 LAYOUT_AddChild, ButtonObject,
  185.                                     GA_ID, GAD_DEL,
  186.                                     GA_Text, "_Delete",
  187.                                     GA_RelVerify, TRUE,
  188.                                     ButtonEnd,
  189.                                 CHILD_NominalSize, TRUE,
  190.                                 CHILD_WeightedWidth, 0,
  191.  
  192.                                 LAYOUT_AddChild, ButtonObject,
  193.                                     GA_ID, GAD_CANCEL,
  194.                                     GA_Text, " _Cancel ",
  195.                                     GA_RelVerify, TRUE,
  196.                                     ButtonEnd,
  197.                                 CHILD_NominalSize, TRUE,
  198.                                 CHILD_WeightedWidth, 0,
  199.  
  200.                                 LayoutEnd,
  201.                             CHILD_WeightedHeight, 0,
  202.                             LayoutEnd)
  203.         {
  204.             struct MsgPort *app_port;
  205.  
  206.             /* Create a message port for App* messages.  This is needed for
  207.              * iconification.  We're being a touch naughty by not checking
  208.              * the return code, but that just means that iconification won't
  209.              * work, nothing really bad will happen.
  210.              */
  211.             app_port = CreateMsgPort();
  212.  
  213.             /* Create the window object.
  214.              */
  215.             if (window_obj = WindowObject,
  216.                                 WA_Left, 0,
  217.                                 WA_Top, screen->Font->ta_YSize + 3,
  218.                                 WA_CustomScreen, screen,
  219.                                 WA_IDCMP, IDCMP_CLOSEWINDOW,
  220.                                 WA_Flags, WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET |
  221.                                             WFLG_SIZEGADGET | WFLG_ACTIVATE | WFLG_SMART_REFRESH,
  222.                                 WA_Title, "Environmental Variable Editor",
  223.                                 WA_NewLookMenus, TRUE,
  224.                                 WINDOW_ParentGroup, layout,
  225.                                 WINDOW_IconifyGadget, TRUE,
  226.                                 WINDOW_Icon, GetDiskObject("PROGDIR:EnvEdit"),
  227.                                 WINDOW_IconTitle, "EnvEdit",
  228.                                 WINDOW_AppPort, app_port,
  229.                                 TAG_DONE))
  230.             {
  231.                 /* Increase the initial hieght.
  232.                  */
  233.                 SetAttrs(window_obj,
  234.                     WA_InnerHeight, screen->Font->ta_YSize * 15,
  235.                     TAG_DONE);
  236.  
  237.                 /*  Open the window.
  238.                  */
  239.                 if (win = (struct Window *)CA_OpenWindow(window_obj))
  240.                 {
  241.                     Object *arexx_obj;
  242.  
  243.                     /* Create host object.
  244.                      */
  245.                     if (arexx_obj = ARexxObject,
  246.                                         AREXX_HostName, "INDEXEDIT",
  247.                                         AREXX_Commands, arexx_cmds,
  248.                                         End)
  249.                     {
  250.                         /* Input Event Loop
  251.                          */
  252.                         while (ok)
  253.                         {
  254.                             ULONG signal, winsig, rxsig;
  255.                             ULONG result;
  256.     
  257.                             /* Obtain the window and ARexx wait signal masks.
  258.                              */
  259.                             GetAttr(WINDOW_SigMask, window_obj, &winsig);
  260.                             GetAttr(AREXX_SigMask, arexx_obj, &rxsig);        
  261.     
  262.                             signal = Wait(rxsig | winsig | (1L << app_port->mp_SigBit) | SIGBREAKF_CTRL_C);
  263.     
  264.                             /* ARexx event?
  265.                              */
  266.                             if (signal & rxsig)
  267.                                 CA_HandleRexx(arexx_obj);
  268.  
  269.                             /* Window event?
  270.                              */
  271.                             if (signal & winsig)
  272.                             {
  273.                                 /* CA_HandleInput() returns the gadget ID of a clicked
  274.                                  * gadget, or one of several pre-defined values.  For
  275.                                  * this demo, we're only actually interested in a
  276.                                  * close window and a couple of gadget clicks.
  277.                                  */
  278.                                 while ((result = CA_HandleInput(window_obj, NULL)) != WMHI_LASTMSG)
  279.                                 {
  280.                                     switch(result & WMHI_CLASSMASK)
  281.                                     {
  282.                                         case WMHI_CLOSEWINDOW:
  283.                                             ok = FALSE;
  284.                                             break;
  285.         
  286.                                         case WMHI_GADGETUP:
  287.                                             switch (result & WMHI_GADGETMASK)
  288.                                             {
  289.                                                 case GAD_LIST:
  290.                                                     D( PutStr("Load text\n"); )
  291.                                                     load_text(win);
  292.                                                     break;
  293.         
  294.                                                 case GAD_EDIT:
  295.                                                     D( PutStr("Text edited\n"); )
  296.                                                     {
  297.                                                         struct Node *node;
  298.         
  299.                                                         GetAttr(LISTBROWSER_SelectedNode, list_gad, (ULONG *)&node);
  300.                                                         if (node)
  301.                                                         {
  302.                                                             struct LBUserData *lbud;
  303.                                                             ULONG flags;
  304.         
  305.                                                             /* Gotta change a flag in
  306.                                                              * our special user data
  307.                                                              * structure.
  308.                                                              */
  309.                                                             GetListBrowserNodeAttrs(node,
  310.                                                                 LBNA_Flags, &flags,
  311.                                                                 LBNA_UserData, &lbud,
  312.                                                                 TAG_DONE);
  313.                                                             if (lbud && !(flags & LBFLG_HASCHILDREN))
  314.                                                                 lbud->lbud_Changed = TRUE;
  315.                                                         }
  316.                                                     }
  317.                                                     break;
  318.         
  319.                                                 case GAD_SAVE:
  320.                                                     save_changed(&file_list, TRUE);
  321.                                                     ok = FALSE;
  322.                                                     break;
  323.                                                     
  324.                                                 case GAD_DEL:
  325.                                                     D( PutStr("Marking file as deleted\n"); )
  326.                                                     {
  327.                                                         struct Node *node;
  328.         
  329.                                                         GetAttr(LISTBROWSER_SelectedNode, list_gad, (ULONG *)&node);
  330.                                                         if (node)
  331.                                                         {
  332.                                                             struct LBUserData *lbud;
  333.                                                             ULONG flags;
  334.         
  335.                                                             SetGadgetAttrs(list_gad, win, NULL, LISTBROWSER_Labels, ~0, TAG_END);
  336.                                                             
  337.                                                             GetListBrowserNodeAttrs( node, LBNA_UserData, &lbud, LBNA_Flags, &flags, TAG_END);
  338.                                                             flags |= LBFLG_CUSTOMPENS;
  339.                                                             if (lbud)
  340.                                                                 lbud->lbud_Deleted = TRUE;
  341.                                                             SetListBrowserNodeAttrs( node, LBNCA_FGPen, drinfo->dri_Pens[HIGHLIGHTTEXTPEN], LBNA_Flags, flags, TAG_END);
  342.         
  343.                                                             if (SetGadgetAttrs(list_gad, win, NULL, LISTBROWSER_Labels, &file_list, LISTBROWSER_Selected, -1, TAG_END))
  344.                                                                 RefreshGList(list_gad, win, NULL, 1);
  345.  
  346.                                                             if (SetGadgetAttrs(edit_gad, win, NULL, TEXTFIELD_Text, "", TAG_END))
  347.                                                                 RefreshGList(edit_gad, win, NULL, 1);
  348.                                                         }
  349.                                                     }
  350.                                                     break;
  351.         
  352.                                                 case GAD_CANCEL:
  353.                                                     ok = FALSE;
  354.                                                     break;
  355.         
  356.                                                 default:
  357.                                                     break;
  358.                                             }
  359.                                             break;
  360.         
  361.                                         case WMHI_ICONIFY:
  362.                                             if (CA_Iconify(window_obj))
  363.                                                 win = NULL;
  364.                                             break;
  365.                                      
  366.                                         case WMHI_UNICONIFY:
  367.                                             win = CA_OpenWindow(window_obj);
  368.                                             break;
  369.         
  370.                                         default:
  371.                                             break;
  372.                                     }
  373.                                 }
  374.                             }
  375.                             /* CTRL-C should quit.
  376.                              */
  377.                             if (signal & SIGBREAKF_CTRL_C)
  378.                             {
  379.                                 ok = FALSE;
  380.                             }
  381.                         }
  382.                         /* Free up ARexx.
  383.                          */
  384.                         DisposeObject(arexx_obj);
  385.                     }
  386.                     else
  387.                         easy_req(NULL, "EnvEdit failed to start\nCouldn't create ARexx host", "Quit", "");
  388.                  }
  389.                 else
  390.                     easy_req(NULL, "EnvEdit failed to start\nCouldn't open window", "Quit", "");
  391.  
  392.                 /* Disposing of the window object will also close the
  393.                  * window if it is already opened and it will dispose of
  394.                  * all objects attached to it.
  395.                  */
  396.                 DisposeObject(window_obj);
  397.             }
  398.             else
  399.                 easy_req(NULL, "EnvEdit failed to start\nCouldn't create window", "Quit", "");
  400.  
  401.             /* Lose the App* message port.
  402.              */
  403.             if (app_port)
  404.                 DeleteMsgPort(app_port);
  405.         }
  406.         else
  407.             easy_req(NULL, "EnvEdit failed to start\nCouldn't create layout", "Quit", "");
  408.  
  409.         free_list(&file_list);
  410.  
  411.         if (drinfo)
  412.             FreeScreenDrawInfo(screen, drinfo);
  413.  
  414.         UnlockPubScreen(0, screen);
  415.     }
  416.     else
  417.         easy_req(NULL, "EnvEdit failed to start\nCouldn't lock destination screen", "Quit", "");
  418.  
  419.     exit(0);
  420. }
  421.  
  422.  
  423. /* Load text for the currently selected item in the variable list into the
  424.  * textfield gadget.
  425.  */
  426. VOID load_text(struct Window *win)
  427. {
  428.     struct Node *node;
  429.  
  430.     SetGadgetAttrs(edit_gad, win, NULL,
  431.         TEXTFIELD_Text, "",
  432.         TAG_DONE);
  433.  
  434.     /* Get the selected node.
  435.      */
  436.     GetAttr(LISTBROWSER_SelectedNode, list_gad, (ULONG *)&node);
  437.     if (node)
  438.     {
  439.         struct LBUserData *lbud;
  440.         ULONG flags;
  441.  
  442.         /* We stashed some important info in the userdata, so get that.
  443.          */
  444.         GetListBrowserNodeAttrs(node,
  445.             LBNA_Flags, &flags,
  446.             LBNA_UserData, &lbud,
  447.             TAG_DONE);
  448.         if (lbud && !(flags & LBFLG_HASCHILDREN))
  449.         {
  450.             /* Open up the file for read.
  451.              */
  452.             if (lbud->lbud_FileName)
  453.             {
  454.                 LONG size;
  455.  
  456.                 /* Found out how big the file is.
  457.                  */
  458.                 if (size = file_size(lbud->lbud_FileName))
  459.                 {
  460.                     BPTR fh;
  461.  
  462.                     /* Open up the file for read.
  463.                      */
  464.                     if (fh = Open(lbud->lbud_FileName, MODE_OLDFILE))
  465.                     {
  466.                         /* Allocate a buffer large enough to load the whole
  467.                          * file into, if we don't already have one big enough.
  468.                          */
  469.                         if (size > lbud->lbud_BufSize)
  470.                         {
  471.                             if (lbud->lbud_Buf)
  472.                                 FreeVec(lbud->lbud_Buf);
  473.                             lbud->lbud_Buf = (STRPTR)AllocVec(size + 1, MEMF_ANY);
  474.                             lbud->lbud_BufSize = size + 1;
  475.                         }
  476.                         
  477.                         if (lbud->lbud_Buf)
  478.                         {
  479.                             /* Go ahead and load our text in.
  480.                              */
  481.                             lbud->lbud_BufSize = Read(fh, lbud->lbud_Buf, size);
  482.                             lbud->lbud_Buf[lbud->lbud_BufSize] = '\0';
  483.  
  484.                             /* Tell the edit gadget to display it.
  485.                              */
  486.                             SetGadgetAttrs(edit_gad, win, NULL,
  487.                                 TEXTFIELD_Text, lbud->lbud_Buf,
  488.                                 TAG_DONE);
  489.                         }
  490.                         else
  491.                         {
  492.                             D( PutStr("No buffer\n"); )
  493.                             lbud->lbud_BufSize = 0;
  494.                         }
  495.                         
  496.                         Close(fh);
  497.                     }
  498.                     D( else PutStr("Can't open file\n"); )
  499.                 }
  500.                 D( else PutStr("No file size\n"); )
  501.             }
  502.             D( else PutStr("No filename\n"); )
  503.         }
  504.         else if (flags & LBFLG_HASCHILDREN)
  505.         {
  506.             ULONG relevent;
  507.  
  508.             GetAttr(LISTBROWSER_RelEvent, list_gad, &relevent);
  509.             if (relevent != LBRE_SHOWCHILDREN && relevent != LBRE_HIDECHILDREN)
  510.             {
  511.                 SetGadgetAttrs(list_gad, win, NULL,
  512.                     LISTBROWSER_Labels, ~0,
  513.                     TAG_DONE);
  514.  
  515.                 if (flags & LBFLG_SHOWCHILDREN)
  516.                     HideListBrowserNodeChildren(node);
  517.                 else
  518.                     ShowListBrowserNodeChildren(node, 1);
  519.  
  520.                 SetGadgetAttrs(list_gad, win, NULL,
  521.                     LISTBROWSER_Labels, &file_list,
  522.                     TAG_DONE);
  523.             }
  524.         }
  525.     }
  526.     D( else PutStr("No selected node\n"); )
  527. }
  528.  
  529. /* Get the file size (in bytes) of a file.
  530.  */
  531. LONG file_size(char *filename)
  532. {
  533.     BPTR lock;
  534.     LONG size = -1;
  535.  
  536.     if (lock = Lock(filename, ACCESS_READ))
  537.     {
  538.         struct FileInfoBlock *fib;
  539.  
  540.         if (fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_END))
  541.         {
  542.             if (Examine(lock, fib))
  543.                 size = fib->fib_Size;
  544.             FreeDosObject(DOS_FIB, fib);
  545.         }
  546.         UnLock(lock);
  547.     }
  548.     return(size);
  549. }
  550.  
  551.  
  552. /* Save all changed variables to the specified directory.
  553.  */
  554. VOID save_changed(struct List *list, BOOL nochange)
  555. {
  556.     struct Node *node;
  557.  
  558.     /* Peruse all nodes.
  559.      */
  560.     for (node = list->lh_Head; node->ln_Succ; node = node->ln_Succ)
  561.     {
  562.         struct LBUserData *lbud;
  563.         ULONG flags;
  564.  
  565.         /* Get our user data structure.
  566.          */
  567.         GetListBrowserNodeAttrs(node,
  568.             LBNA_Flags, &flags,
  569.             LBNA_UserData, &lbud,
  570.             TAG_DONE);
  571.         if (lbud && !(flags & LBFLG_HASCHILDREN))
  572.         {
  573.             /* See if the node has changed and if we have a filename
  574.              * and if we have a buffer.
  575.              */
  576.             if (lbud->lbud_Deleted && lbud->lbud_FileName)
  577.                 DeleteFile( lbud->lbud_FileName );
  578.             else
  579.             if (lbud->lbud_Changed && lbud->lbud_FileName)
  580.             {
  581.                 BPTR fh;
  582.  
  583.                 /* Convert the filename.
  584.                  */
  585.                 /* Try and open the file for write.
  586.                  */
  587.                 if (fh = Open(lbud->lbud_FileName, MODE_NEWFILE))
  588.                 {
  589.                     if (lbud->lbud_BufSize == Write(fh, lbud->lbud_Buf, lbud->lbud_BufSize))
  590.                         lbud->lbud_Changed = nochange;
  591.                     Close(fh);
  592.                 }
  593.             }
  594.         }
  595.     }
  596. }
  597.  
  598.  
  599. /* Read files in a directory to a listbrowser list.
  600.  */
  601. BOOL read_files(struct List *list, STRPTR dir, WORD generation)
  602. {
  603.     BPTR lock, file, old;
  604.  
  605.     D( Printf("Read directory: %s\n", dir); )
  606.  
  607.     if (lock = Lock(dir, ACCESS_READ))
  608.     {
  609.         char *eadata;
  610.         
  611.         old = CurrentDir(lock);
  612.  
  613.         if (eadata = (char *)AllocVec(sizeof(struct ExAllData) * 200, MEMF_CLEAR))
  614.         {
  615.             struct ExAllControl *eac;
  616.  
  617.             if (eac = (struct ExAllControl *)AllocDosObject(DOS_EXALLCONTROL, NULL))
  618.             {
  619.                 BOOL more;
  620.  
  621.                 eac->eac_LastKey = 0;
  622.                 do
  623.                 {
  624.                     struct ExAllData *ead;
  625.  
  626.                     more = ExAll(lock, eadata, sizeof(struct ExAllData) * 200, ED_TYPE, eac);
  627.                     if (!more && IoErr() != ERROR_NO_MORE_ENTRIES)
  628.                         return(FALSE);
  629.  
  630.                     if (eac->eac_Entries == 0)
  631.                         return(FALSE);
  632.  
  633.                     ead = (struct ExAllData *)eadata;
  634.                     do
  635.                     {
  636.                         struct Node *node;
  637.                         char temp1[255];
  638.                         
  639.                         if (ead->ed_Type >= 0)
  640.                             continue;
  641.  
  642.                         if (file = Open(ead->ed_Name, MODE_OLDFILE))
  643.                         {
  644.                             int l;
  645.                             FGets(file, temp1, 120);
  646.                             if (l = strlen(temp1)) 
  647.                                 temp1[l-1] = 0;
  648.                             FGets(file, temp1+120, 120);
  649.                             if (l = strlen(temp1+120))
  650.                                 temp1[l-1+120] = 0;
  651.                             Close(file);
  652.                         }
  653.  
  654.                         if (node = AllocListBrowserNode(4,
  655.                                         LBNA_Column, 0,
  656.                                             LBNCA_CopyText, TRUE,
  657.                                             LBNCA_Text, temp1,
  658.                                         LBNA_Column, 1,
  659.                                             LBNCA_CopyText, TRUE,
  660.                                             LBNCA_Text, temp1+120,
  661.                                         LBNA_Column, 2,
  662.                                             LBNCA_CopyText, TRUE,
  663.                                             LBNCA_Text, ead->ed_Name,
  664.                                         TAG_DONE))
  665.                         {
  666.                             struct LBUserData *lbud;
  667.  
  668.                             AddTail(list, (struct Node *)node);
  669.  
  670.                             strcpy(temp1, dir);
  671.                             AddPart(temp1, ead->ed_Name, sizeof(temp1));
  672.  
  673.                             if (lbud = (struct LBUserData *)AllocVec(sizeof(struct LBUserData), MEMF_CLEAR))
  674.                             {
  675.                                 stccpy(lbud->lbud_FileName, temp1, sizeof(lbud->lbud_FileName));
  676.  
  677.                                 SetListBrowserNodeAttrs(node,
  678.                                     LBNA_UserData, lbud,
  679.                                     TAG_DONE);
  680.                             }
  681.                         }
  682.  
  683.                         ead = ead->ed_Next;
  684.                     } while (ead);
  685.                 } while (more);
  686.  
  687.                 FreeDosObject(DOS_EXALLCONTROL, eac);
  688.             }
  689.             else
  690.                 return(FALSE);
  691.             FreeVec(eadata);
  692.         }
  693.         else
  694.             return(FALSE);
  695.             
  696.         CurrentDir(old);
  697.         UnLock(lock);
  698.     }
  699.     else
  700.         return(FALSE);
  701.  
  702.     return(TRUE);
  703. }
  704.  
  705.  
  706. /* Copy a B string to a C string.
  707.  */
  708. VOID bstrcpy(STRPTR cstr, BSTR bstr)
  709. {
  710.     strncpy(cstr, (char *)BADDR(bstr) + 1, ((char *)BADDR(bstr))[0]);
  711.     cstr[((char *)BADDR(bstr))[0]] = '\0';
  712. }
  713.  
  714.  
  715. /* Function to free an Exec List.
  716.  */
  717. VOID free_list(struct List *list)
  718. {
  719.     struct Node *node, *nextnode;
  720.  
  721.     node = list->lh_Head;
  722.     while (nextnode = node->ln_Succ)
  723.     {
  724.         struct LBUserData *lbud;
  725.  
  726.         GetListBrowserNodeAttrs(node,
  727.             LBNA_UserData, &lbud,
  728.             TAG_DONE);
  729.         if (lbud)
  730.         {
  731.             if (lbud->lbud_Buf);
  732.                 FreeVec(lbud->lbud_Buf);
  733.             FreeVec(lbud);
  734.         }
  735.  
  736.         FreeListBrowserNode(node);
  737.         node = nextnode;
  738.     }
  739.     NewList(list);
  740. }
  741.  
  742.  
  743. /* Do an easy requester.
  744.  */
  745. LONG easy_req(struct Window *win, char *reqtext, char *reqgads, char *reqargs, ...)
  746. {
  747.     struct EasyStruct general_es =
  748.     {
  749.         sizeof(struct EasyStruct),
  750.         0,
  751.         "SBGen",
  752.         NULL,
  753.         NULL
  754.     };
  755.  
  756.     general_es.es_TextFormat = reqtext;
  757.     general_es.es_GadgetFormat = reqgads;
  758.  
  759.     return(EasyRequestArgs(win, &general_es, NULL, &reqargs));
  760. }
  761.  
  762. /* NAME
  763.  */
  764. VOID SAVEDS ASM rexx_name(REG_A0 struct ARexxCmd *ac, REG_A1 struct RexxMsg *rxm)
  765. {
  766.     ac->ac_Result = "IndexEdit";
  767. }
  768.  
  769. /* VERSION
  770.  */
  771. VOID SAVEDS ASM rexx_version(REG_A0 struct ARexxCmd *ac, REG_A1 struct RexxMsg *rxm)
  772. {
  773.     ac->ac_Result = "1.0";
  774. }
  775.  
  776. /* AUTHOR
  777.  */
  778. VOID SAVEDS ASM rexx_author(REG_A0 struct ARexxCmd *ac, REG_A1 struct RexxMsg *rxm)
  779. {
  780.     ac->ac_Result = "Osma Ahvenlampi";
  781. }
  782.  
  783. /* DEACTIVATE
  784.  */
  785. VOID SAVEDS ASM rexx_deactivate(REG_A0 struct ARexxCmd *ac, REG_A1 struct RexxMsg *rxm)
  786. {
  787.     if (CA_Iconify(window_obj))
  788.         win = NULL;
  789. }
  790.  
  791. /* ACTIVATE
  792.  */
  793. VOID SAVEDS ASM rexx_activate(REG_A0 struct ARexxCmd *ac, REG_A1 struct RexxMsg *rxm)
  794. {
  795.     win = CA_OpenWindow(window_obj);
  796. }
  797.  
  798. /* QUIT
  799.  */
  800. VOID SAVEDS ASM rexx_quit(REG_A0 struct ARexxCmd *ac, REG_A1 struct RexxMsg *rxm)
  801. {
  802.     ok = FALSE;
  803. }
  804.  
  805. /* 
  806.  */
  807. VOID SAVEDS ASM rexx_windowtoback(REG_A0 struct ARexxCmd *ac, REG_A1 struct RexxMsg *rxm)
  808. {
  809.     WindowToBack(win);
  810. }
  811.  
  812. /* WINDOWTOFRONT
  813.  */
  814. VOID SAVEDS ASM rexx_windowtofront(REG_A0 struct ARexxCmd *ac, REG_A1 struct RexxMsg *rxm)
  815. {
  816.     WindowToFront(win);
  817. }
  818.