home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / pref_helpers.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  69.8 KB  |  2,656 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /* 
  19.    pref_helpers.c --- Preference->Helper dialogs.
  20.    Created: Dora Hsu <dora@netscape.com>, 25-Mar-96.
  21. */
  22.  
  23.  
  24. #include "mozilla.h"
  25. #include "xlate.h"
  26. #include "xfe.h"
  27. #include "nslocks.h"
  28. #include "secnav.h"
  29. #include "mozjava.h"
  30. #include "prnetdb.h"
  31. #include "e_kit.h"
  32. #include "pref_helpers.h"
  33. #include "np.h"
  34.  
  35. #include <Xm/Label.h>
  36. #include <Xfe/Xfe.h>
  37. #include "felocale.h"
  38.  
  39. #ifndef _STDC_
  40. #define _STDC_ 1
  41. #define HACKED_STDC 1
  42. #endif
  43.  
  44. #include <XmL/Grid.h>
  45. #include <XmL/Folder.h>
  46.  
  47. #ifdef HACKED_STDC
  48. #undef HACKED_STDC
  49. #undef _STDC_
  50. #endif
  51.  
  52. #include "xp_sec.h"
  53. #include "msgcom.h"
  54.  
  55. /* for XP_GetString() */
  56. #include <xpgetstr.h>
  57. extern int XFE_NO_PLUGINS;
  58. extern int XFE_HELPERS_NETSCAPE;
  59. extern int XFE_HELPERS_UNKNOWN;
  60. extern int XFE_HELPERS_SAVE;
  61. extern int XFE_HELPERS_PLUGIN;
  62. extern int XFE_HELPERS_EMPTY_MIMETYPE;
  63. extern int XFE_HELPERS_LIST_HEADER;
  64. extern int XFE_HELPERS_PLUGIN_DESC_CHANGE;
  65.  
  66. #define DEFAULT_COLUMN_WIDTH     35     
  67. #define MAX_COLUMN_WIDTH     100    
  68.  
  69. #define FE_MOZILLA_MIME_COMMENT        "#mime types added by Netscape Helper"
  70. #define FE_MOZILLA_MAILCAP_COMMENT    "#mailcap entry added by Netscape Helper"
  71. #define TYPE                "type"
  72. #define DESC                "desc"
  73. #define ENC                "enc"
  74. #define ICON                "icon"
  75. #define LANG                "lang"
  76. #define EXTS                "exts"
  77. #define ALT                "alt"
  78. #define SPACE                " "
  79.  
  80. /* For sys_errlist and sys_nerr */
  81. #include "prprf.h"
  82. #include "libi18n.h"
  83. #include "fonts.h"
  84.  
  85. /* External Methods */
  86. void fe_browse_file_of_text (MWContext *context, Widget text_field,
  87.                              Boolean dirp);
  88.  
  89. void fe_UnmanageChild_safe (Widget w);
  90.  
  91. /* From prefdialogs.c */
  92. void fe_MarkHelpersModified(MWContext *context);
  93.  
  94. /* Internal Methods */
  95. static void
  96. fe_helpers_application_browse_cb(Widget widget, XtPointer closure,
  97.                                  XtPointer call_data);
  98. static void
  99. fe_helpers_set_handle_by_cb (Widget w, XtPointer closure, 
  100.                              XtPointer call_data );
  101.  
  102. static void
  103. fe_helpers_append_type_to_list(struct fe_prefs_helpers_data *fep,
  104.                                NET_cdataStruct *cd_item, 
  105.                                NET_mdataStruct *md, int pos);
  106.  
  107. /*===================== A pile of string manipulation=======================*/
  108. static int /* returns len of token */
  109. fe_GetToken (char *mess, char *token, int *n) /* n: next position to search*/
  110. {
  111.     int len, i, j;
  112.  
  113.     if (mess == NULL)
  114.         return(0);
  115.  
  116.     if (*n > (int)strlen(mess))
  117.         return(0);
  118.  
  119.     i = *n;
  120.     len = strspn(mess+i, " =;\\\t\n\0");
  121.     i += len;
  122.  
  123.     j = i;
  124.     if (mess[i] == '"')
  125.       {
  126.         i++; j++;
  127.         for (len = 0; mess[j] != '\n' && mess[j++] != '"'; len++);
  128.       }
  129.     else
  130.         len = strcspn(mess+i, " =;\\\t\n\0");
  131.     strncpy(token, mess+i, len);
  132.     token[len] = '\0';
  133.  
  134.     if (j > 0 && mess[j-1] == '"') i++;
  135.  
  136.     *n = i + len;
  137.  
  138.     return(len);
  139. }
  140.  
  141. static char*
  142. fe_helpers_appendKey (char *buf, char *key, char *val, Boolean hasSep)
  143. {
  144.     char *newbuf=NULL;
  145.     char  str[80];
  146.     int   len, i;
  147.     
  148.     /* validate inputs here */
  149.     if (!buf || !key || !val ||
  150.         !strlen(buf) || !strlen(key) || !strlen(val))
  151.         return NULL;
  152.     
  153.     if (hasSep)
  154.         sprintf(str, "; \\\n%s=%s", key, val);
  155.     else
  156.         sprintf(str, " \\\n%s=%s", key, val);
  157.     len = strlen(buf);
  158.     for (i = len-1;
  159.          buf[i] == '\n' || buf[i] == '\\' || buf[i] == ' ' || buf[i] == '\t';
  160.          i--);
  161.     i++;
  162.  
  163.     len = strlen(buf) + strlen(str) + 1 + 1;
  164.     newbuf = (char *)malloc(len);
  165.     memset (newbuf, 0, len);
  166.     strncpy (newbuf, buf, i);  /* i-1 */
  167.     newbuf[i] = 0;
  168.     if (newbuf[i-1] == ';') newbuf[i-1] = 0;
  169.     strcat (newbuf, str);
  170.  
  171.     return(newbuf);
  172. }
  173.  
  174. /*----------------------------------------------------------
  175.  
  176. -----------------------------------------------------------*/
  177.  
  178. static char* cleanString(char *newbuf )
  179. {
  180.     int i = 0;
  181.     int found =  0;
  182.  
  183.     while (!found && (int)strlen(newbuf) > 0)
  184.       {
  185.         if ( newbuf[strlen(newbuf)-1] == ' ' ||
  186.              newbuf[strlen(newbuf)-1] == '\\' ||
  187.              newbuf[strlen(newbuf)-1] == ';' ||
  188.              newbuf[strlen(newbuf)-1] == '\n' ||
  189.              newbuf[strlen(newbuf)-1] == '\t' )
  190.           {
  191.             newbuf[strlen(newbuf)-1] = '\0';
  192.           }
  193.         else found = 1;
  194.       }
  195.  
  196.     found = 0;
  197.     i = 0;
  198.     while (!found && (int)strlen(newbuf) > 0 && i < (int)strlen(newbuf))
  199.       {
  200.         if ( newbuf[i] == '\\' ||
  201.              newbuf[i] == ';' )
  202.           {
  203.             strncpy( newbuf, newbuf+i+1, strlen(newbuf)-i);
  204.           }
  205.         else found = 1;
  206.         i++;
  207.       }
  208.  
  209.     return newbuf;
  210. }
  211.  
  212.  
  213. static char*
  214. fe_helpers_deleteKey (char *buf, char *key, Boolean hasSep)
  215. {
  216.     char *newbuf=NULL;
  217.     char  tok[80];
  218.     int   len, i, j = 0, k = 0, n;
  219.     int   found = 0;
  220.     int   quote = 0;
  221.  
  222.     /* validate inputs here */
  223.     if (!buf || !key ||
  224.         !strlen(buf) || !strlen(key))
  225.         return NULL;
  226.  
  227.     len = strlen(buf);
  228.     i = 0;
  229.     while (!found && i < len)
  230.       {
  231.         j = i;
  232.         n = fe_GetToken(buf, tok, &i);
  233.         if (strcmp(tok, key) == 0)
  234.           {
  235.             n = strspn(buf+i, " \t\n");
  236.             i += n;
  237.             if (buf[i] == '=')
  238.               {
  239.                 n = strspn(buf+i, " =\"\t\n");
  240.                 if ( buf[i+n-1] == '\"')
  241.                     quote = 1;
  242.                 k = i + n;
  243.                 if (hasSep)
  244.                     len = strcspn (buf+k, ";");
  245.                 else
  246.                   {
  247.                     if ( quote )
  248.                       {
  249.                         n = strcspn(buf+k, "\""); /* end quote*/
  250.                         if ( buf[k+n] == '\"')
  251.                             k = k + n;
  252.                         quote = 0;
  253.                       }
  254.                     len = strcspn (buf+k, " \t\\");
  255.                   }
  256.                 i = k + len;
  257.                 found = 1;
  258.               }
  259.           }
  260.         else
  261.           {
  262.             n = strspn(buf+i, " ;\\\t\n");
  263.             i += n;
  264.           }
  265.       }
  266.     if (found)
  267.       {
  268.         newbuf = strdup (buf);
  269.         newbuf[j] = '\0';
  270.         found = 0;
  271.         newbuf = cleanString(newbuf);
  272.         strcat (newbuf, buf+i);
  273.         newbuf = cleanString(newbuf);
  274.  
  275.         /*
  276.           if( newbuf[strlen(newbuf)-1] != '\n' ) strcat(newbuf, "\n");
  277.           */
  278.       }
  279.     return(newbuf);
  280. }
  281. /*----------------------------------------------------------
  282.  
  283. -----------------------------------------------------------*/
  284.  
  285. static char*
  286. fe_helpers_updateKey (char *buf, char *key, char *newVal, Boolean hasSep)
  287. {
  288.     char *newbuf=NULL;
  289.     char  tok[80];
  290.     int   len, i, k, n;
  291.     int   found = 0;
  292.     int   quote = 0;
  293.  
  294.     /* validate inputs here */
  295.     if (!buf || !key || !newVal ||
  296.         !strlen(buf) || !strlen(key) || !strlen(newVal))
  297.         return NULL;
  298.  
  299.     len = strlen(buf);
  300.     i = 0;
  301.  
  302.     while (!found && i < len)
  303.       {
  304.         n = fe_GetToken(buf, tok, &i);
  305.         if (strcmp(tok, key) == 0)
  306.           {
  307.             n = strspn(buf+i, " \t\n");
  308.             i += n;
  309.             if (buf[i] == '=')
  310.               {
  311.                 n = strspn(buf+i, " =\"\t\n");
  312.                 if ( buf[i+n-1]== '\"')
  313.                     quote = 1;
  314.                 k = i + n;
  315.  
  316.                 if (hasSep)
  317.                     len = strcspn (buf+k, ";");
  318.                 else
  319.                   {
  320.                     if ( quote )
  321.                       {
  322.                         len = strcspn(buf+k, "\""); /* end quote*/
  323.                         quote = 0;
  324.                       }
  325.                     else
  326.                         len = strcspn (buf+k, " \t\\");
  327.                   }
  328.  
  329.                 strncpy(tok, buf+k, len);
  330.                 tok[len] = '\0';
  331.                 i = k + len;
  332.                 found = 1;
  333.               }
  334.           }
  335.       }
  336.  
  337.  
  338.     if (found)
  339.       {
  340.         len = strlen(buf) - strlen(tok) + strlen(newVal) + 3;
  341.         newbuf = (char *)malloc (len);
  342.         memset (newbuf, 0, len);
  343.         strncpy(newbuf, buf, k);
  344.         newbuf[k] = 0;
  345.         if (tok[0] == '"')
  346.             strcat (newbuf, "\"");
  347.         strcat (newbuf, newVal);
  348.         if (tok[0] == '"')
  349.             strcat (newbuf, "\"");
  350.         strcat (newbuf, buf+i);
  351.       }
  352.     return(newbuf);
  353. }
  354.  
  355. /*----------------------------------------------------------
  356. -----------------------------------------------------------*/
  357. static char*
  358. fe_helpers_addCommand(char *buf, char *command)
  359. {
  360.     char *newbuf=0;
  361.     int   len, i, n, j;
  362.  
  363.     /* validate inputs here */
  364.     if (!buf || !command ||
  365.         !strlen(buf) || !strlen(command))
  366.         return 0;
  367.  
  368.     len = strlen(buf) + strlen(command) +
  369.       strlen(";") * 2 + strlen("\n") + 1;
  370.  
  371.     j = strlen(buf);
  372.     newbuf = (char *)malloc (len);
  373.     memset(newbuf, '\0', len);
  374.  
  375.     /* buf is the src string. Hence skip any comments that are preceding
  376.      * the actual specification. Then find the place of the ';'.
  377.      */
  378.     n = 0;
  379.     n += strspn(&buf[n], " \t\n");
  380.     while (buf[n] && buf[n] == '#') 
  381.       {
  382.         n++;
  383.         /* Skip until and including the newline */
  384.         while (buf[n] && buf[n] != '\n') n++;
  385.         n += strspn(&buf[n], " \t\n");
  386.       }
  387.     if (buf[n] == '\0')
  388.         /* No entry. The entire entry was a comment. Punt. */
  389.         return(0);
  390.     n += strcspn (&buf[n], ";");        /* find the ';' */
  391.  
  392.     if ( buf[n] == ';' )
  393.       {
  394.         j = n+1;
  395.  
  396.         if ( j < (int)strlen(buf) )
  397.           {
  398.             i = strcspn (buf+j, ";"); /* find the second ";" */
  399.  
  400.             /* If the second semicolon is missing, it is right for us
  401.              * to assume its presence at the end.
  402.              */
  403.             j = j+i+1;
  404.           }
  405.       }
  406.  
  407.     strncpy(newbuf, buf, n);
  408.     newbuf[n] = '\0';
  409.     strcat (newbuf, ";");
  410.     strcat (newbuf, command);
  411.     if (j < (int)strlen(buf))  /* more entries after command */
  412.       {
  413.         strcat (newbuf, ";");
  414.         strcat (newbuf, buf + j);
  415.       }
  416.     /*
  417.       strcat (newbuf, "\n");
  418.       */
  419.  
  420.     return(newbuf);
  421. }
  422.  
  423. static char*
  424. fe_helpers_deleteCommand(char *buf)
  425. {
  426.     char *newbuf=0;
  427.     int   len, i, n, j;
  428.  
  429.     /* validate inputs here */
  430.     if (!buf || !strlen(buf))
  431.         return 0;
  432.  
  433.     len = strlen(buf) + 1;
  434.     j = strlen(buf);
  435.  
  436.     newbuf = (char *)malloc (len);
  437.     memset(newbuf, '\0', len);
  438.  
  439.     /* buf is the src string. Hence skip any comments that are preceding
  440.      * the actual specification. Then find the place of the ';'.
  441.      */
  442.     n = 0;
  443.     n += strspn(&buf[n], " \t\n");
  444.     while (buf[n] && buf[n] == '#') 
  445.       {
  446.         n++;
  447.         /* Skip until and including the newline */
  448.         while (buf[n] && buf[n] != '\n') n++;
  449.         n += strspn(&buf[n], " \t\n");
  450.       }
  451.     if (buf[n] == '\0')
  452.         /* No entry. The entire entry was a comment. Punt. */
  453.         return(0);
  454.     n += strcspn (&buf[n], ";");        /* find the ';' */
  455.  
  456.     if ( buf[n] == ';' )
  457.       {
  458.         j = n+1;
  459.  
  460.         if ( j < (int)strlen(buf) )
  461.           {
  462.             i = strcspn (buf+j, ";"); /* find the second ";" */
  463.             j = j +i;
  464.  
  465.             if ( j < (int)strlen(buf) && buf[j] == ';' )
  466.                 j = j + 1;
  467.           }
  468.       }
  469.  
  470.     strncpy(newbuf, buf, n);
  471.     newbuf[n] = '\0';
  472.     if (j < (int)strlen(buf))  /* more entries after command */
  473.       {
  474.         strcat (newbuf, ";");
  475.         strcat (newbuf, ";");
  476.         strcat (newbuf, buf + j);
  477.       }
  478.     /*
  479.       strcat (newbuf, "\n");
  480.       */
  481.  
  482.     return newbuf;
  483. }
  484.  
  485. /*======================== A pile of callbacks  ========================*/
  486. void
  487. fe_helpers_add_new_mailcap_data(char *contenttype, char* src_str,
  488.                                 char *command, char *xmode, Boolean isLocal)
  489. {
  490.     NET_mdataStruct *md = 0;
  491.  
  492.     md = NET_mdataCreate();
  493.     if ( md )
  494.       {
  495.         md->contenttype = 0;
  496.         md->command = 0;
  497.         md->label = 0;
  498.         md->testcommand = 0;
  499.         md->printcommand = 0;
  500.         md->stream_buffer_size = 0;
  501.         md->xmode = 0;
  502.         md->src_string = 0;
  503.         md->is_modified = 1;
  504.         md->is_local = isLocal;
  505.         if ( contenttype  && *contenttype )
  506.             StrAllocCopy(md->contenttype, contenttype );
  507.         if ( command && *command )
  508.             StrAllocCopy(md->command, command);
  509.         if ( xmode && *xmode )
  510.             StrAllocCopy(md->xmode, xmode);
  511.         if ( src_str && *src_str )
  512.             StrAllocCopy(md->src_string, src_str);
  513.         NET_mdataAdd(md);
  514.       }
  515. }
  516.  
  517. static Boolean
  518. fe_helpers_is_deleted_type (NET_cdataStruct *cd_item)
  519. {
  520.     NET_mdataStruct *md_item = 0;
  521.  
  522.     /* Check if this mime is deleted from the list */
  523.  
  524.     md_item = fe_helpers_get_mailcap_from_type(cd_item->ci.type);
  525.  
  526.     if ( md_item && md_item->xmode && *md_item->xmode )
  527.         if ( !XP_STRCASECMP(md_item->xmode, NET_COMMAND_DELETED))
  528.             return True;
  529.         else return False;
  530.     else if (md_item && (!md_item->command|| !*md_item->command))
  531.         return True;
  532.  
  533.     return False;
  534. }
  535.  
  536. static void
  537. fe_helpers_plugin_selected(struct fe_prefs_helpers_data *fep, char *pluginName)
  538. {
  539.     /* Change the description and extensions to what the plugins says */
  540.     char *mimetype, *desc=NULL, *ext=NULL;
  541.     char *cur_desc=NULL, *cur_ext=NULL;
  542.     XP_Bool differ = True;
  543.  
  544.     mimetype = fe_GetTextField(fep->mime_types_text);
  545.  
  546.     if (fe_GetMimetypeInfoFromPlugin(pluginName, mimetype, &desc, &ext) >= 0) {
  547.       /* If either the description or the extension is different from what is
  548.        * already being displayed, ask the user whether to revert to what the
  549.        * plugin says.
  550.        */
  551.       cur_desc = fe_GetTextField(fep->mime_types_desc_text);
  552.       cur_ext = fe_GetTextField(fep->mime_types_suffix_text);
  553.      
  554.       if (desc) differ = strcmp(desc, cur_desc);
  555.       else differ = *cur_desc;
  556.      
  557.       if (!differ)
  558.           if (ext) differ = strcmp(ext, cur_ext);
  559.           else differ = *cur_ext;
  560.  
  561.       if (differ) {
  562.         char *buf;
  563.         buf = PR_smprintf(XP_GetString(XFE_HELPERS_PLUGIN_DESC_CHANGE),
  564.                           mimetype, desc?desc:"", ext?ext:"");
  565.         if (FE_Confirm(fep->context, buf)) {
  566.           XtVaSetValues(fep->mime_types_desc_text, XmNcursorPosition, 0, 0);
  567.           fe_SetTextField(fep->mime_types_desc_text, desc);
  568.           XtVaSetValues(fep->mime_types_suffix_text, XmNcursorPosition, 0, 0);
  569.           fe_SetTextField(fep->mime_types_suffix_text, ext);
  570.         }
  571.         if (buf) XP_FREE(buf);
  572.       }
  573.     }
  574.  
  575.     if (mimetype) XP_FREE(mimetype);
  576.     if (cur_desc) XP_FREE(cur_desc);
  577.     if (cur_ext) XP_FREE(cur_ext);
  578. }
  579.  
  580. static void
  581. fe_helpers_plugin_sel_cb(Widget widget, XtPointer closure, XtPointer call_data)
  582. {
  583.     struct fe_prefs_helpers_data *fep =
  584.       (struct fe_prefs_helpers_data *) closure;
  585.     int n = 0;
  586.     char *pluginName;
  587.  
  588.     if (!XmToggleButtonGetState(fep->plugin_b)) return;
  589.  
  590.     XtVaGetValues(widget, XmNuserData, &n, 0);
  591.     pluginName = fep->plugins[n];
  592.     fe_helpers_plugin_selected(fep, pluginName);
  593. }
  594.  
  595. static void
  596. fe_helpers_build_plugin_list(struct fe_prefs_helpers_data *fep,
  597.                              char *mime_type_to_find)
  598. {
  599.     int i;
  600.     Cardinal ac;
  601.     Arg av[20];
  602.     Widget button = 0, current = 0;
  603.     char namebuf[64];
  604.     char **plugins = NULL, *current_plugin = NULL;
  605.     NET_mdataStruct *md = NULL;
  606.   
  607.     if (!fep) return;
  608.     if (mime_type_to_find  && *mime_type_to_find)
  609.         plugins = NPL_FindPluginsForType(mime_type_to_find);
  610.   
  611.     /* Destroy all existing children */
  612.     if (fep->plugin_pulldown) {
  613.       int nkids = 0;
  614.       Widget *kids;
  615.       XtVaGetValues(fep->plugin_pulldown, XmNchildren, &kids,
  616.                     XmNnumChildren, &nkids, 0);
  617.       if (nkids > 0) {
  618.         /* Conditions for not destroy are
  619.          *    1. If we didn't have plugins previously and dont have any now
  620.          * in all other cases, we destroy.
  621.          */
  622.         if (nkids == 1 && !strcmp(XtName(kids[0]), "plugin0"))
  623.             if (!plugins)
  624.                 return;
  625.         fe_DestroyWidgetTree(kids, nkids);
  626.       }
  627.     }
  628.   
  629.     if (plugins && plugins[0]) {
  630.       md = fe_helpers_get_mailcap_from_type(mime_type_to_find);
  631.       if (fe_IsMailcapEntryPlugin(md))
  632.           current_plugin = fe_GetPluginNameFromMailcapEntry(md);
  633.     
  634.       i = 0;
  635.       while (plugins[i]) {
  636.         sprintf(namebuf, "plugin%d", i+1);
  637.         ac = 0;
  638.         XtSetArg (av[ac], XmNuserData, i); ac++;
  639.         button =  XmCreatePushButtonGadget(fep->plugin_pulldown, namebuf,
  640.                                            av, ac);
  641.         fe_SetString(button, XmNlabelString, plugins[i]);
  642.         XtAddCallback (button, XmNactivateCallback,
  643.                        fe_helpers_plugin_sel_cb, fep);
  644.         XtManageChild(button);
  645.         if (current_plugin && !strcmp(current_plugin, plugins[i]))
  646.             current = button;
  647.         i++;
  648.       }
  649.       fep->plugins = plugins;
  650.     }
  651.     if (!button) {
  652.       /* No plugins installed for this mime type */
  653.       ac = 0;
  654.       XtSetArg (av[ac], XmNsensitive, False); ac++;
  655.       button =  XmCreatePushButtonGadget(fep->plugin_pulldown, "plugin0",
  656.                                          av, ac);
  657.       fe_SetString(button, XmNlabelString, XP_GetString(XFE_NO_PLUGINS));
  658.       XtManageChild(button);
  659.       XtVaSetValues(fep->plugin_option, XmNsensitive, False, 0);
  660.       XtVaSetValues(fep->plugin_b, XmNsensitive, False, 0);
  661.       current = button;
  662.     }
  663.     else {
  664.       XtVaSetValues(fep->plugin_b, XmNsensitive, True, 0);
  665.       if (!current) current = button;
  666.     }
  667.     XtVaSetValues(fep->plugin_option, XmNmenuHistory, current, 0);    
  668. }
  669.  
  670. static void
  671. fe_helpers_build_exts(char *ext, NET_cdataStruct *cd)
  672. {
  673.     int n = cd->num_exts;
  674.  
  675.     cd->exts = (char **) (n ? XP_REALLOC(cd->exts, (n+1)*sizeof(char *))
  676.                           : XP_ALLOC(sizeof(char *)));
  677.  
  678.     if(!cd->exts)
  679.         return;
  680.  
  681.     cd->exts[n] = 0;
  682.     StrAllocCopy(cd->exts[n], ext);
  683.     cd->num_exts = ++n;
  684. }
  685. static char *
  686. fe_helpers_construct_new_mailcap_string(NET_mdataStruct *md, char* contenttype,
  687.                                         char *command, char *flag)
  688. {
  689.     char *str = NULL;
  690.     char *buf0 = 0;
  691.     char buf1[1024];
  692.     char buf2[1024];
  693.     int  len;
  694.  
  695.  
  696.     memset(buf1, '\0', 1024);
  697.     memset(buf2, '\0', 1024);
  698.  
  699.     if ( !md && !contenttype ) 
  700.         return str;
  701.     else if ( command && *command && flag && *flag )
  702.       {
  703.         sprintf(buf1, "%s\n%s;%s", FE_MOZILLA_MAILCAP_COMMENT,
  704.                 md? md->contenttype: contenttype ,command );
  705.    
  706.         sprintf(buf2, ";\\\n\t%s=%s", NET_MOZILLA_FLAGS, flag);
  707.  
  708.         len = strlen(buf1)+strlen(buf2)+1;
  709.  
  710.         buf0 = (char*)malloc(len*sizeof(char));
  711.         memset(buf0, '\0', len);
  712.         strcpy(buf0, buf1);
  713.         strcat(buf0, buf2);
  714.       }
  715.     else if ( command && *command )
  716.       { /* APPLICATION MODE */
  717.         sprintf(buf1, "%s\n%s;%s", FE_MOZILLA_MAILCAP_COMMENT,
  718.                 md ? md->contenttype: contenttype , command);
  719.  
  720.         len = strlen(buf1)+1;
  721.         buf0 = (char*)malloc(len*sizeof(char));
  722.         memset(buf0, '\0', len);
  723.  
  724.         strcpy(buf0, buf1);
  725.       }
  726.     else if ( flag && *flag ) 
  727.       {
  728.         sprintf(buf1, "%s\n%s;", FE_MOZILLA_MAILCAP_COMMENT,
  729.                 md? md->contenttype: contenttype );
  730.         sprintf(buf2, ";\\\n\t%s=%s", NET_MOZILLA_FLAGS, flag);
  731.  
  732.         len = strlen(buf1)+strlen(buf2)+1;
  733.  
  734.         buf0 = (char*)malloc(len*sizeof(char));
  735.         memset(buf0, '\0', len);
  736.         strcpy(buf0, buf1);
  737.         strcat(buf0, buf2);
  738.       }
  739.     else
  740.       {
  741.         sprintf(buf1, "%s\n%s;", FE_MOZILLA_MAILCAP_COMMENT,
  742.                 md? md->contenttype: contenttype );
  743.         sprintf(buf2, ";\\\n\t%s=%s", NET_MOZILLA_FLAGS, NET_COMMAND_UNKNOWN);
  744.  
  745.         len = strlen(buf1)+strlen(buf2)+1;
  746.  
  747.         buf0 = (char*)malloc(len*sizeof(char));
  748.         memset(buf0, '\0', len);
  749.         strcpy(buf0, buf1);
  750.         strcat(buf0, buf2);
  751.  
  752.  
  753.       }
  754.  
  755.     memset(buf1, '\0', strlen(buf1));
  756.     memset(buf2, '\0', strlen(buf2));
  757.     if (md &&  md->label && *md->label)
  758.         sprintf(buf1, ";\\\n\t%s=%s", "description", md->label );
  759.     if ( md && md->testcommand && *md->testcommand)
  760.         sprintf(buf2, ";\\\n\t%s=%s", "test", md->testcommand );
  761.     len = strlen(buf0)+strlen(buf1)+strlen(buf2)+strlen("\n")+1;
  762.     str = (char*)malloc(len*sizeof(char));
  763.     memset(str, '\0', len);
  764.     strcpy(str, buf0);
  765.     strcat(str, buf1);
  766.     strcat(str, buf2);
  767.     free(buf0);
  768.     buf0 = 0;
  769.     return str;
  770. }
  771.  
  772. void
  773. fe_helpers_update_mailcap_entry (char *mimeType, NET_mdataStruct *md,
  774.                                  char *flag )
  775. {
  776.     char *oldStr = NULL;
  777.     char *src_str = 0;
  778.  
  779.     if (md)
  780.       {
  781.         oldStr = md->src_string;
  782.         md->src_string = 0;
  783.       }
  784.  
  785.     if ( !oldStr || !strlen(oldStr) ) 
  786.         src_str = fe_helpers_construct_new_mailcap_string (md, mimeType,     
  787.                                                            md? md->command: NULL,flag);
  788.     else 
  789.       {
  790.         src_str = fe_helpers_updateKey(oldStr, NET_MOZILLA_FLAGS, flag, True);
  791.  
  792.         if ( !src_str )
  793.             src_str = fe_helpers_appendKey(oldStr, NET_MOZILLA_FLAGS, flag, 1);
  794.         
  795.         XP_FREE(oldStr);
  796.       }
  797.  
  798.     if ( md )
  799.       {
  800.         if ( md->src_string ) XP_FREE(md->src_string);
  801.         if ( src_str && *src_str)
  802.             md->src_string = src_str;
  803.         if ( md->xmode ) XP_FREE(md->xmode);
  804.         md->xmode = strdup(flag);
  805.         md->is_modified = 1;
  806.       }
  807.     else {
  808.       fe_helpers_add_new_mailcap_data(mimeType, src_str, NULL, flag, 1);
  809.       XP_FREE(src_str);
  810.     }
  811.  
  812. static void
  813. fe_helpers_build_handle(struct fe_prefs_helpers_data *fep)
  814. {
  815.     NET_mdataStruct *old_md = NULL;
  816.     char *src_str;
  817.     char *oldStr = NULL;
  818.  
  819.     old_md = fe_helpers_get_mailcap_from_type(fep->cd->ci.type);
  820.  
  821.     /* old_md might be marked "Deleted", but that's okay */
  822.     /* because we will replace it with the new md data value */
  823.  
  824.     if ( XmToggleButtonGetState(fep->navigator_b) )
  825.       {
  826.         fe_helpers_update_mailcap_entry(fep->cd->ci.type, old_md,
  827.                                         NET_COMMAND_NETSCAPE);
  828.             
  829.       }
  830.     else if (XmToggleButtonGetState(fep->plugin_b))
  831.       {
  832.         Widget w;
  833.         char *value;
  834.         int n = 0;
  835.         XtVaGetValues(fep->plugin_option, XmNmenuHistory, &w, 0);
  836.         XtVaGetValues(w, XmNuserData, &n, 0);
  837.         value = PR_smprintf("%s%s", NET_COMMAND_PLUGIN,
  838.                             fep->plugins[n]);
  839.         fe_helpers_update_mailcap_entry(fep->cd->ci.type, old_md, value);
  840.         XP_FREE(value);
  841.       }
  842.     else if (XmToggleButtonGetState(fep->app_b))
  843.       {
  844.         char * text = fe_GetTextField(fep->app_text);
  845.         if ( text && *text)
  846.           {
  847.             text = fe_StringTrim(text);
  848.  
  849.             if( old_md )
  850.               {
  851.                 oldStr = old_md->src_string;
  852.                 old_md->src_string = 0;
  853.               }
  854.  
  855.             if ( !oldStr || !strlen(oldStr) ) 
  856.                 src_str = fe_helpers_construct_new_mailcap_string
  857.                   (old_md, fep->cd->ci.type, text, NULL);
  858.             else 
  859.               {
  860.                 src_str = fe_helpers_addCommand (oldStr, text);
  861.                 XP_FREE(oldStr);
  862.  
  863.                 oldStr = src_str;
  864.                 src_str = fe_helpers_deleteKey(oldStr, NET_MOZILLA_FLAGS, 1);
  865.                 if ( src_str )
  866.                     XP_FREE(oldStr);
  867.                 else src_str = oldStr;
  868.  
  869.               }
  870.  
  871.             if ( old_md )
  872.               {
  873.                 StrAllocCopy(old_md->command, text);
  874.                 if ( old_md->src_string )
  875.                     XP_FREE(old_md->src_string);
  876.                 old_md->src_string = 0;
  877.                 if ( src_str && *src_str )
  878.                     old_md->src_string = src_str;
  879.                 if (old_md->xmode) XP_FREE(old_md->xmode);
  880.                 old_md->xmode = 0;
  881.                 old_md->is_modified = 1;
  882.               }
  883.             else
  884.               {
  885.                 fe_helpers_add_new_mailcap_data(fep->cd->ci.type,
  886.                                                 src_str,text, NULL, 1);
  887.                 XP_FREE(src_str);
  888.               }
  889.           }
  890.         else
  891.           {
  892.             if ( old_md )
  893.               {
  894.                 oldStr = old_md->src_string;
  895.                 old_md->src_string = 0;
  896.               }
  897.             if ( !oldStr || !strlen(oldStr) ) 
  898.               {
  899.                 src_str = fe_helpers_construct_new_mailcap_string
  900.                   (old_md, fep->cd->ci.type, NULL, NET_COMMAND_UNKNOWN);
  901.               }
  902.             else 
  903.               {
  904.                 src_str = fe_helpers_deleteCommand(oldStr); 
  905.                 XP_FREE(oldStr);
  906.  
  907.                 oldStr = src_str;
  908.                 src_str = fe_helpers_updateKey(oldStr, NET_MOZILLA_FLAGS,
  909.                                                NET_COMMAND_UNKNOWN, True);
  910.                 if ( !src_str )
  911.                     src_str = fe_helpers_appendKey ( oldStr, NET_MOZILLA_FLAGS,
  912.                                                      NET_COMMAND_UNKNOWN, 1);
  913.  
  914.                 XP_FREE(oldStr);
  915.               }
  916.             if ( old_md )
  917.               {
  918.                 StrAllocCopy(old_md->command, text);
  919.                 if ( old_md->src_string ) 
  920.                     XP_FREE(old_md->src_string);
  921.                 old_md->src_string = 0;
  922.                 if ( src_str && *src_str )
  923.                     old_md->src_string = src_str;
  924.                 if (old_md->xmode) XP_FREE(old_md->xmode);
  925.                 old_md->xmode = strdup(NET_COMMAND_UNKNOWN);
  926.                 old_md->is_modified = 1;
  927.               }
  928.             else
  929.               {
  930.                 fe_helpers_add_new_mailcap_data(fep->cd->ci.type,
  931.                                                 src_str,NULL,
  932.                                                 NET_COMMAND_UNKNOWN, 1);
  933.                 XP_FREE(src_str);
  934.               }
  935.           }
  936.         if (text) XP_FREE(text);
  937.       }
  938.     else if (XmToggleButtonGetState(fep->save_b))
  939.       {
  940.         fe_helpers_update_mailcap_entry(fep->cd->ci.type, old_md,
  941.                                         NET_COMMAND_SAVE_TO_DISK);
  942.       }
  943.     else /* Everything else, we set it to be unknown */
  944.       {
  945.         fe_helpers_update_mailcap_entry(fep->cd->ci.type, old_md,
  946.                                         NET_COMMAND_UNKNOWN);
  947.       }
  948.         
  949. }
  950. static Boolean
  951. fe_helpers_get_mime_data_real_pos(NET_cdataStruct *old_cd, int *real_pos)
  952. {
  953.     Boolean found = False; 
  954.     XP_List *infoList = cinfo_MasterListPointer();
  955.     NET_cdataStruct *cd;
  956.  
  957.     if (!infoList) return found;
  958.     *real_pos = 0;
  959.  
  960.     while ((cd=(NET_cdataStruct*)XP_ListNextObject(infoList)))
  961.       {
  962.         if ( !fe_helpers_is_deleted_type(cd) )
  963.           {
  964.             if ( cd->ci.type ) /* should skip the encoding ones which type = null */
  965.               {
  966.                 if ( old_cd == cd )
  967.                   {
  968.                     found = True;
  969.                     break;
  970.                   }
  971.                 else (*real_pos)++;
  972.               }
  973.           }
  974.       }
  975.     return found;
  976. }
  977.  
  978. static NET_cdataStruct *
  979. fe_helpers_get_exist_data(NET_cdataStruct *old_cd, int *old_pos)
  980. {
  981.     NET_cdataStruct *found_cd = NULL;
  982.     NET_cdataStruct *cd = NULL;
  983.     XP_List *infoList = cinfo_MasterListPointer();
  984.  
  985.     *old_pos = 0;
  986.  
  987.     if ( !infoList )
  988.         return found_cd;
  989.  
  990.     while ((cd= (NET_cdataStruct *)XP_ListNextObject(infoList)))
  991.       {
  992.         if ( old_cd->ci.type && cd->ci.type )
  993.           {
  994.             if( !strcasecomp(old_cd->ci.type, cd->ci.type))
  995.               {
  996.                 /* found matching type regardless whether it is deleted one or not */
  997.                 /* caller needs to decide what they want to do with this old_cd */
  998.                 found_cd = cd;
  999.                 break;
  1000.               }
  1001.             else (*old_pos)++;
  1002.           }
  1003.       }
  1004.     return found_cd;
  1005. }
  1006.  
  1007. static NET_cdataStruct *
  1008. fe_helpers_can_combine ( NET_cdataStruct *new_cd, int* old_pos)
  1009. {
  1010.     NET_cdataStruct *old_cd = NULL;
  1011.  
  1012.     old_cd = fe_helpers_get_exist_data(new_cd, old_pos);
  1013.  
  1014.     return old_cd;
  1015. }
  1016.  
  1017. static Boolean 
  1018. fe_helpers_start_new_line( char *old_string, char *de, int n )
  1019. {
  1020.     Boolean yes = False;
  1021.     int i = 1;
  1022.     char *str = 0;
  1023.     char *string = strdup(old_string);
  1024.  
  1025.     while (1) {
  1026.  
  1027.       while ((*string) && XP_IS_SPACE(*string)) ++string;
  1028.  
  1029.       if ( *string && (*string != '#') ) 
  1030.         {
  1031.           if ( string && de && n > 0)
  1032.             {
  1033.               str =  XP_STRTOK( string, de);
  1034.  
  1035.               while (  i < n || str )
  1036.                 {
  1037.                   str = XP_STRTOK(NULL, de);
  1038.                   i++;
  1039.                 }   
  1040.  
  1041.               if ( i >= n ) /* String ended */
  1042.                 {
  1043.                   yes = True;
  1044.                   break;
  1045.                 }
  1046.             }
  1047.         }
  1048.       else
  1049.         {
  1050.           while ((*string) && (*string != '\n')) ++string;
  1051.           if (*string && *string == '\n') string++;
  1052.           else break;
  1053.         }
  1054.     }
  1055.  
  1056.     return yes;
  1057.  
  1058.  
  1059. static char *
  1060. fe_helpers_new_string(char *old_str, char* type,  char *value, char *del)
  1061. {
  1062.     char *str = 0 ;
  1063.     int len = 0;
  1064.     Boolean newline = False;
  1065.     Boolean quoted = False;
  1066.  
  1067.  
  1068.     if ( !value || !*value)
  1069.       {
  1070.         if ( old_str )
  1071.           {
  1072.             str = (char*)malloc((strlen(old_str)+1)*sizeof(char));
  1073.             strcpy(str, old_str);
  1074.             return str;
  1075.           }
  1076.         else return NULL;
  1077.       }
  1078.  
  1079.     if (!old_str)
  1080.       {
  1081.         if ( !strcmp(type, DESC) || !strcmp(type, EXTS) ) 
  1082.           {
  1083.             len = strlen(type) + strlen("=") + strlen(value) + 2 * strlen("\"") 
  1084.               + strlen(del) + 1;
  1085.  
  1086.             str = (char*)malloc(len *sizeof(char));
  1087.             memset(str, '\0', len);
  1088.             strcpy(str, type);
  1089.             strcat(str, "=");
  1090.             strcat(str, "\"");
  1091.             strcat(str, value);
  1092.             strcat(str, "\"");
  1093.             strcat(str, del);
  1094.           }
  1095.         else 
  1096.           {
  1097.             len = strlen(type) +strlen("=") + strlen(value) + 
  1098.               strlen(del) +1;
  1099.  
  1100.             str = (char*)malloc(len *sizeof(char));
  1101.             memset(str, '\0', len);
  1102.             strcpy(str, type);
  1103.             strcat(str, "=");
  1104.             strcat(str, value);
  1105.             strcat(str, del);
  1106.           }
  1107.       }
  1108.     else 
  1109.       {
  1110.         if ( old_str[strlen(old_str)-1] == '\n')
  1111.             old_str[strlen(old_str)-1] = '\0';
  1112.  
  1113.  
  1114.         if (fe_helpers_start_new_line(old_str, del, 2) )
  1115.           {
  1116.             newline = True;
  1117.             len = strlen(" \\\n");
  1118.           }
  1119.  
  1120.         if ( !strcmp(type, DESC) || !strcmp(type, EXTS) ) 
  1121.           {
  1122.             quoted = True;
  1123.             len = len + 2 * strlen("\"") ;
  1124.           }
  1125.  
  1126.  
  1127.         len = len + strlen(old_str)+ strlen("\t\t")+ 
  1128.           strlen(type) + strlen("=") + strlen(value)+ 
  1129.           strlen(del) +   1;
  1130.  
  1131.         str = (char*)malloc(len*sizeof(char));
  1132.         memset(str, '\0', len);
  1133.         strcpy(str, old_str);
  1134.  
  1135.         if ( newline )
  1136.             strcat(str, " \\\n");
  1137.         else
  1138.             strcat(str, "\t\t");
  1139.         strcat(str, type);
  1140.         strcat(str, "=");
  1141.         if (quoted)
  1142.             strcat(str, "\"");
  1143.         strcat(str, value);
  1144.         if (quoted)
  1145.             strcat(str, "\"");
  1146.         strcat(str, del);
  1147.  
  1148.       }
  1149.  
  1150.     return str;
  1151. }
  1152.  
  1153. static char *
  1154. fe_replace_new_mime_string(NET_cdataStruct *old_cd, NET_cdataStruct *new_cd)
  1155. {
  1156.     int n;
  1157.     char old_exts[200];
  1158.     char new_exts[200];
  1159.     char *str = NULL;
  1160.     char *old_str = NULL;
  1161.  
  1162.  
  1163.  
  1164.     if ( !old_cd->src_string ) return NULL;
  1165.     str = strdup(old_cd->src_string);
  1166.     memset(old_exts, '\0', 200);
  1167.     memset(new_exts, '\0', 200);
  1168.  
  1169.     if (old_cd->ci.type && *old_cd->ci.type )
  1170.       {
  1171.         if (new_cd->ci.type && *new_cd->ci.type ) 
  1172.           {
  1173.             old_str = str;
  1174.             str = fe_helpers_updateKey(old_str, TYPE, new_cd->ci.type, 0 );
  1175.  
  1176.             if ( !str )
  1177.               {
  1178.                 str = fe_helpers_new_string(old_str, TYPE,
  1179.                                             new_cd->ci.type, SPACE);
  1180.               }
  1181.             XP_FREE(old_str);
  1182.           }
  1183.         else 
  1184.           {
  1185.             old_str = str;
  1186.             str = fe_helpers_deleteKey(str, TYPE, 0 );
  1187.             XP_FREE(old_str);
  1188.           }
  1189.     
  1190.       }
  1191.     else
  1192.       {
  1193.         old_str = str;
  1194.         str = fe_helpers_new_string(str, TYPE,
  1195.                                     new_cd->ci.type, SPACE);
  1196.         XP_FREE(old_str);
  1197.       }
  1198.  
  1199.  
  1200.  
  1201.     if (old_cd->ci.desc && *old_cd->ci.desc )
  1202.       {
  1203.         if (new_cd->ci.desc && *new_cd->ci.desc ) 
  1204.           {
  1205.             old_str = str;
  1206.             str = fe_helpers_updateKey(str, DESC, new_cd->ci.desc, 0 );
  1207.             
  1208.             if ( !str )
  1209.               {
  1210.                 str = fe_helpers_new_string(old_str, DESC,
  1211.                                             new_cd->ci.desc, SPACE);
  1212.               }
  1213.             XP_FREE(old_str);
  1214.           }
  1215.         else 
  1216.           {
  1217.             old_str = str;
  1218.             str = fe_helpers_deleteKey(str, DESC,0 );
  1219.             XP_FREE(old_str);
  1220.           }
  1221.       }
  1222.     else
  1223.       {
  1224.         old_str = str;
  1225.         str = fe_helpers_new_string(str, DESC,
  1226.                                     new_cd->ci.desc, SPACE);
  1227.         XP_FREE(old_str);
  1228.       }
  1229.  
  1230.     if ( old_cd->exts && *old_cd->exts )
  1231.       {
  1232.         for (n= 0; n < old_cd->num_exts; n++ )
  1233.           {
  1234.             if ( n > 0 )
  1235.                 strcat( old_exts, ",");
  1236.             if ( n == 0 )
  1237.                 strcpy(old_exts, old_cd->exts[n]);
  1238.             else
  1239.                 strcat(old_exts, old_cd->exts[n]);
  1240.           }
  1241.  
  1242.         if ( new_cd->num_exts > 0 )
  1243.           { 
  1244.  
  1245.             for (n= 0; n < new_cd->num_exts; n++ )
  1246.               {
  1247.                 if ( n > 0 )
  1248.                     strcat( new_exts, ",");
  1249.                 if ( n == 0 )
  1250.                     strcpy(new_exts, new_cd->exts[n]);
  1251.                 else
  1252.                     strcat(new_exts, new_cd->exts[n]);
  1253.               }
  1254.             old_str = str;
  1255.             str = fe_helpers_updateKey(str, EXTS, new_exts, 0 );
  1256.             if ( !str )
  1257.               {
  1258.                 str = fe_helpers_new_string(old_str, EXTS,
  1259.                                             new_exts, SPACE);
  1260.               }
  1261.             XP_FREE(old_str);
  1262.           }
  1263.         else
  1264.           {
  1265.             old_str = str;
  1266.             str = fe_helpers_deleteKey(str, EXTS, 0);
  1267.             XP_FREE(old_str);
  1268.           }
  1269.       }
  1270.     else
  1271.       {
  1272.         if ( new_cd->num_exts > 0 )
  1273.           { 
  1274.  
  1275.             for (n= 0; n < new_cd->num_exts; n++ )
  1276.               {
  1277.                 if ( n > 0 )
  1278.                     strcat( new_exts, ",");
  1279.                 strcat(new_exts, new_cd->exts[n]);
  1280.               }
  1281.             old_str = str;
  1282.             str = fe_helpers_new_string(str, EXTS,
  1283.                                         new_exts, SPACE);
  1284.             XP_FREE(old_str);
  1285.           }
  1286.       }
  1287.  
  1288.     return str;
  1289. }
  1290.  
  1291. static char *
  1292. fe_helpers_construct_new_mime_string(NET_cdataStruct *new_cd)
  1293. {
  1294.     int n;
  1295.     int len;
  1296.     char buffer1[1024];
  1297.     char buffer2[1024];
  1298.     char *string = 0;
  1299.     char *str = 0;
  1300.     char *old_str = NULL;
  1301.     XP_List *masterList = cinfo_MasterListPointer();
  1302.  
  1303.     strcpy(buffer1, FE_MOZILLA_MIME_COMMENT);
  1304.     if ( NET_IsOldMimeTypes(masterList) )
  1305.       {
  1306.         sprintf(buffer2, "%s", new_cd->ci.type); 
  1307.         if ( new_cd->num_exts > 0 ) 
  1308.             for ( n = 0; n < new_cd->num_exts; n++ )
  1309.               {
  1310.                 if (n == 0 ) 
  1311.                     strcat(buffer2, SPACE);
  1312.                 else 
  1313.                     strcat(buffer2, SPACE);
  1314.                 strcat(buffer2, new_cd->exts[n]);
  1315.               }
  1316.         len = strlen(buffer1)+strlen(buffer2)+ 2*strlen("\n")+1;
  1317.         string = (char*)malloc(len *sizeof(char));
  1318.         strcpy(string, buffer1);
  1319.         strcat(string, "\n");
  1320.         strcat(string, buffer2);
  1321.       }
  1322.     else
  1323.       {
  1324.         n = 0;
  1325.         if ( new_cd->ci.type &&  *new_cd->ci.type )
  1326.           {
  1327.             str = fe_helpers_new_string(old_str, TYPE, new_cd->ci.type, SPACE);
  1328.             XP_FREE(old_str);
  1329.           }
  1330.         if ( new_cd->ci.encoding && *new_cd->ci.encoding )
  1331.           {
  1332.             old_str = str;
  1333.             str = fe_helpers_new_string(old_str, ENC, new_cd->ci.encoding, SPACE);
  1334.             XP_FREE(old_str);
  1335.           }
  1336.  
  1337.         if ( new_cd->ci.language && *new_cd->ci.language)
  1338.           {
  1339.             old_str = str;
  1340.             str = fe_helpers_new_string(old_str, LANG, new_cd->ci.language, SPACE);
  1341.             XP_FREE(old_str);
  1342.           }
  1343.  
  1344.         if ( new_cd->ci.desc && *new_cd->ci.desc)
  1345.           {
  1346.             old_str = str;
  1347.             str = fe_helpers_new_string(old_str, DESC, 
  1348.                                         new_cd->ci.desc, SPACE);
  1349.             XP_FREE(old_str);
  1350.           }
  1351.  
  1352.         if ( new_cd->ci.alt_text && *new_cd->ci.alt_text)
  1353.           {
  1354.             old_str = str;
  1355.             str = fe_helpers_new_string(old_str, ALT, new_cd->ci.alt_text, SPACE);
  1356.             XP_FREE(old_str);
  1357.           }
  1358.  
  1359.         if ( new_cd->ci.icon && *new_cd->ci.icon)
  1360.           {
  1361.             old_str = str;
  1362.             str = fe_helpers_new_string(old_str, ICON, new_cd->ci.icon, SPACE);
  1363.             XP_FREE(old_str);
  1364.           }
  1365.  
  1366.         if ( new_cd->exts && *new_cd->exts)
  1367.           {
  1368.             char exts[1024];
  1369.  
  1370.             memset(exts, '\0', 1024);
  1371.             for (n= 0; n < new_cd->num_exts; n++ )
  1372.               {
  1373.                 if ( n > 0 )
  1374.                     strcat( exts, ",");
  1375.                 strcat(exts, new_cd->exts[n]);
  1376.               }
  1377.             
  1378.             old_str = str;
  1379.             str = fe_helpers_new_string(old_str, EXTS, exts, SPACE);
  1380.             XP_FREE(old_str);
  1381.           }
  1382.         len = strlen(buffer1)+strlen(str)+ 2 *strlen("\n") + 1;
  1383.         string = (char*)malloc(len *sizeof(char));
  1384.         memset(string, '\0', len);
  1385.         strcpy(string, buffer1);
  1386.         strcat(string, "\n");
  1387.         strcat(string, str);
  1388.       }
  1389.  
  1390.     return string;
  1391. }
  1392.  
  1393. static void
  1394. fe_helpers_done_cb(Widget widget, XtPointer closure, XtPointer call_data)
  1395. {
  1396.     struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure;
  1397.     char *text = 0;
  1398.     char *u = 0;
  1399.     int i;
  1400.     int old_pos;
  1401.     NET_cdataStruct *old_cd = NULL;
  1402.     NET_cdataStruct *new_cd = NULL;
  1403.     NET_mdataStruct *md = NULL;
  1404.     Boolean add_new_cd = False;
  1405.     char *src_string =0;
  1406.     int real_pos;
  1407.  
  1408.     fe_MarkHelpersModified(fep->context);
  1409.  
  1410.     /* Type  is critical. If this field is empty, then basically we don't
  1411.        do a thing here */
  1412.  
  1413.     text = fe_GetTextField(fep->mime_types_text);
  1414.     if ( !text ) return;
  1415.     text = fe_StringTrim(text);
  1416.     if ( !strlen(text)) {
  1417.       FE_Alert(fep->context, XP_GetString(XFE_HELPERS_EMPTY_MIMETYPE));
  1418.       XP_FREE(text); 
  1419.       return;
  1420.     }
  1421.  
  1422.     if(text) XP_FREE(text);
  1423.  
  1424.     /* Empty type Business has been taken care of */
  1425.     /* Do some serious stuff here now...*/
  1426.  
  1427.     new_cd = NET_cdataCreate();
  1428.     new_cd->is_local = True;
  1429.     if ( fep->cd )
  1430.       {
  1431.         new_cd->is_external = fep->cd->is_external;
  1432.         new_cd->is_modified = 1;
  1433.       }
  1434.     else{
  1435.       new_cd->is_external = 1;
  1436.       new_cd->is_modified = 1;
  1437.  
  1438.       /* If new entry was deleted before commit, we don't want to save the info out*/
  1439.       new_cd->is_new = 1; /* remember this for deletion*/
  1440.  
  1441.       add_new_cd = True;
  1442.     }
  1443.  
  1444.  
  1445.     /* Description */
  1446.     text = fe_GetTextField(fep->mime_types_desc_text);
  1447.     if ( text && *text ) {
  1448.       fe_StringTrim(text);
  1449.       StrAllocCopy(new_cd->ci.desc, text);
  1450.     }
  1451.     if(text) XP_FREE(text);
  1452.  
  1453.     /* Type */
  1454.     text = fe_GetTextField(fep->mime_types_text);
  1455.     if ( text && *text ){
  1456.       fe_StringTrim(text);
  1457.       StrAllocCopy( new_cd->ci.type, text);
  1458.     }
  1459.     if(text) XP_FREE(text);
  1460.  
  1461.     /* Suffix */
  1462.     text = fe_GetTextField(fep->mime_types_suffix_text);
  1463.     u = XP_STRTOK(text, ",");
  1464.  
  1465.     while (u) 
  1466.       {
  1467.         u = fe_StringTrim(u);
  1468.         fe_helpers_build_exts(u, new_cd);
  1469.         u = XP_STRTOK(NULL, ",");
  1470.       }
  1471.     if(text) XP_FREE(text);
  1472.  
  1473.  
  1474.     if ( (old_cd=fe_helpers_can_combine (new_cd, &old_pos)) )
  1475.       {
  1476.         if ( !fe_helpers_is_deleted_type(old_cd) )
  1477.           { 
  1478.             /* Only cd's that aren't deleted are displayed in the list */
  1479.             /* Therefore, we need to make sure if the item is in the list */
  1480.             /* in order to delete */
  1481.  
  1482.             if ( fe_helpers_get_mime_data_real_pos(old_cd, &real_pos) )
  1483.                 old_pos = real_pos;
  1484.  
  1485.             if ( old_pos > fep->pos ) 
  1486.                 XmLGridDeleteRows(fep->helpers_list, XmCONTENT, old_pos, 1);
  1487.             else if (fep->pos > old_pos )
  1488.               {
  1489.       
  1490.                 XmLGridDeleteRows(fep->helpers_list, XmCONTENT, old_pos, 1);
  1491.                 fep->pos -= 1;
  1492.               }
  1493.             else if ( fep->pos == 0 && old_pos == 0)
  1494.               {
  1495.                 XmLGridDeleteRows(fep->helpers_list, XmCONTENT, old_pos, 1);
  1496.               }
  1497.           }
  1498.  
  1499.         /* CanCombine=True will remove the fep->cd from the list */
  1500.         /* Therefore, make the new one the current */
  1501.         /* If action = add_new_cd, and can_combine = true, we should remove the old one */
  1502.         if ( add_new_cd ) 
  1503.           {
  1504.             NET_cdataRemove(old_cd);
  1505.             old_cd = NULL;
  1506.           }
  1507.       }
  1508.  
  1509.  
  1510.     if ( fep->cd ) /* Then, this is not an action: NEW  */
  1511.       {
  1512.  
  1513.         if ( !fep->cd->is_local && !fep->cd->is_external )
  1514.           {
  1515.             /* read from Global mime.type in old mime format */
  1516.             /* convert it to the new format here */
  1517.             src_string = fe_helpers_construct_new_mime_string( new_cd );
  1518.           }
  1519.         else if ( !fep->cd->is_local && !fep->cd->num_exts )
  1520.           {
  1521.             /* This entry is added by an existing mailcap type */
  1522.             src_string = fe_helpers_construct_new_mime_string(new_cd);
  1523.           }
  1524.         else    
  1525.             src_string = fe_replace_new_mime_string( fep->cd, new_cd );
  1526.  
  1527.         XP_FREE(fep->cd->src_string);
  1528.         fep->cd->src_string = src_string;
  1529.  
  1530.         XP_FREE(fep->cd->ci.desc );
  1531.         XP_FREE(fep->cd->ci.type );
  1532.  
  1533.         fep->cd->ci.desc = 0;
  1534.         fep->cd->ci.type = 0;
  1535.  
  1536.         for ( i = 0; i < fep->cd->num_exts; i++ )
  1537.             XP_FREE (fep->cd->exts[i]);
  1538.         XP_FREE(fep->cd->exts);
  1539.  
  1540.         fep->cd->exts = 0;
  1541.         fep->cd->num_exts = 0;
  1542.         fep->cd->is_external = new_cd->is_external;
  1543.         fep->cd->is_modified = new_cd->is_modified;
  1544.         StrAllocCopy(fep->cd->ci.desc, new_cd->ci.desc);
  1545.         StrAllocCopy(fep->cd->ci.type, new_cd->ci.type);
  1546.         for ( i = 0; i < new_cd->num_exts; i++ )
  1547.             fe_helpers_build_exts(new_cd->exts[i], fep->cd);
  1548.  
  1549.         NET_cdataFree(new_cd);
  1550.       }
  1551.     else {
  1552.       src_string = fe_helpers_construct_new_mime_string( new_cd );
  1553.       if ( new_cd->src_string) XP_FREE(new_cd->src_string);
  1554.       new_cd->src_string = src_string;
  1555.       fep->cd = new_cd;
  1556.     }
  1557.  
  1558.     fe_helpers_build_handle(fep);
  1559.     if ( add_new_cd && (fep->pos == 0)) 
  1560.       {
  1561.         fep->pos = -1;
  1562.         NET_cdataAdd(fep->cd);
  1563.       }
  1564.  
  1565.     if ( !fe_helpers_is_deleted_type(fep->cd) )
  1566.       {
  1567.         md = fe_helpers_get_mailcap_from_type(fep->cd->ci.type);
  1568.         fe_helpers_append_type_to_list(fep, fep->cd, md,  fep->pos);
  1569.       }
  1570.  
  1571.     XtDestroyWidget(widget);
  1572. }
  1573.  
  1574.  
  1575. static void
  1576. fe_helpers_cancel_cb(Widget widget, XtPointer closure, XtPointer call_data)
  1577. {
  1578.     XtDestroyWidget(widget);
  1579. }
  1580.  
  1581. static void
  1582. fe_helpers_destroy_cb (Widget widget, XtPointer closure, XtPointer call_data)
  1583. {
  1584.     struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure;
  1585.     int i;
  1586.  
  1587.     if (!fep->editor)
  1588.         /* The helper edit dialog is not up. Do nothing. */
  1589.         return;
  1590.  
  1591.     fep->editor = NULL;
  1592.     fep->pos = 0;
  1593.     fep->cd = NULL;
  1594.  
  1595.     /* Free the backend allocated plugin names */
  1596.     for (i=0; fep->plugins && fep->plugins[i]; i++)
  1597.         XP_FREE(fep->plugins[i]);
  1598.     if (fep->plugins) XP_FREE(fep->plugins);
  1599.     fep->plugins = 0;
  1600. }
  1601.  
  1602. static void
  1603. fe_helpers_verify_toggle_cb( Widget widget, XtPointer closure,
  1604.                              XtPointer call_data)
  1605. {
  1606.     struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure;
  1607.     XmToggleButtonCallbackStruct *cb =
  1608.       (XmToggleButtonCallbackStruct *)call_data;
  1609.  
  1610.  
  1611.     if (!cb->set)
  1612.       {
  1613.         XtVaSetValues (widget, XmNset, True, 0);
  1614.       }
  1615.     else if (widget == fep->navigator_b)
  1616.       {
  1617.         XtVaSetValues (fep->plugin_b, XmNset, False, 0);
  1618.         XtVaSetValues (fep->app_b, XmNset, False, 0);
  1619.         XtVaSetValues (fep->save_b, XmNset, False, 0);
  1620.         XtVaSetValues (fep->app_text, XmNsensitive, False, 0);
  1621.         XtVaSetValues (fep->unknown_b, XmNset, False, 0);
  1622.       }
  1623.     else if (widget == fep->plugin_b)
  1624.       {
  1625.         Widget w;
  1626.         int n;
  1627.         char *pluginName;
  1628.  
  1629.         XtVaGetValues(fep->plugin_option, XmNmenuHistory, &w, 0);
  1630.         XtVaGetValues(w, XmNuserData, &n, 0);
  1631.         pluginName = fep->plugins[n];
  1632.         fe_helpers_plugin_selected(fep, pluginName);
  1633.  
  1634.         XtVaSetValues (fep->navigator_b, XmNset, False, 0);
  1635.         XtVaSetValues (fep->app_b, XmNset, False, 0);
  1636.         XtVaSetValues (fep->save_b, XmNset, False, 0);
  1637.         XtVaSetValues (fep->app_text, XmNsensitive, False, 0);
  1638.         XtVaSetValues (fep->unknown_b, XmNset, False, 0);
  1639.       }
  1640.     else if (widget == fep->app_b)
  1641.       {
  1642.         XtVaSetValues (fep->navigator_b, XmNset, False, 0);
  1643.         XtVaSetValues (fep->plugin_b, XmNset, False, 0);
  1644.         XtVaSetValues (fep->save_b, XmNset, False, 0);
  1645.         XtVaSetValues (fep->app_text, XmNsensitive, True, 0);
  1646.         XtVaSetValues (fep->unknown_b, XmNset, False, 0);
  1647.       }
  1648.     else if (widget == fep->save_b)
  1649.       {
  1650.         XtVaSetValues (fep->navigator_b, XmNset, False, 0);
  1651.         XtVaSetValues (fep->plugin_b, XmNset, False, 0);
  1652.         XtVaSetValues (fep->app_b, XmNset, False, 0);
  1653.         XtVaSetValues (fep->app_text, XmNsensitive, False, 0);
  1654.         XtVaSetValues (fep->unknown_b, XmNset, False, 0);
  1655.       }
  1656.     else if (widget == fep->unknown_b)
  1657.       {
  1658.         XtVaSetValues (fep->navigator_b, XmNset, False, 0);
  1659.         XtVaSetValues (fep->plugin_b, XmNset, False, 0);
  1660.         XtVaSetValues (fep->app_b, XmNset, False, 0);
  1661.         XtVaSetValues (fep->app_text, XmNsensitive, False, 0);
  1662.         XtVaSetValues (fep->save_b, XmNset, False, 0);
  1663.       }
  1664.     else
  1665.         abort ();
  1666. }
  1667.  
  1668. static Widget
  1669. fe_helpers_make_edit_dialog(struct fe_prefs_helpers_data *fep)
  1670. {
  1671.     Widget mainw = CONTEXT_WIDGET (fep->context);
  1672.     Widget dialog;
  1673.     Widget frame1;
  1674.     Widget form, form1, form2;
  1675.     Widget mime_types_desc_label, mime_types_desc_text;
  1676.     Widget mime_types_label, mime_types_text;
  1677.     Widget mime_types_suffix_label, mime_types_suffix_text;
  1678.     Widget navigator_b, plugin_b, app_b, app_text, app_browse;
  1679.     Widget save_b, unknown_b;
  1680.     Widget label1;
  1681.     Widget kids[30];
  1682.  
  1683.     Widget plugin_option;
  1684.     Widget plugin_pulldown;
  1685.  
  1686.     Dimension size, space;
  1687.  
  1688.     Visual *v = 0;
  1689.     Colormap cmap = 0;
  1690.     Cardinal depth = 0;
  1691.     Arg av[20];
  1692.     int ac;
  1693.     int i;
  1694.  
  1695.     /* If the pref is up, we need to make this the child of the pref dialog */
  1696.     if (CONTEXT_DATA(fep->context)->currentPrefDialog)
  1697.         mainw = CONTEXT_DATA(fep->context)->currentPrefDialog;
  1698.     while(!XtIsWMShell(mainw) && (XtParent(mainw)!=0))
  1699.         mainw = XtParent(mainw);
  1700.  
  1701.  
  1702.     XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap,
  1703.                    XtNdepth, &depth, 0);
  1704.     ac = 0;
  1705.     XtSetArg (av[ac], XmNvisual, v); ac++;
  1706.     XtSetArg (av[ac], XmNdepth, depth); ac++;
  1707.     XtSetArg (av[ac], XmNcolormap, cmap); ac++;
  1708.     XtSetArg (av[ac], XmNtransientFor, mainw); ac++;
  1709.     XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
  1710.     XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); ac++;
  1711.     XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++;
  1712.     XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
  1713.     XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
  1714.     /*  XtSetArg (av[ac], XmNnoResize, True); ac++; */
  1715.     dialog = XmCreatePromptDialog (mainw, "helperEditor", av, ac);
  1716.  
  1717.     XtUnmanageChild(XmSelectionBoxGetChild (dialog, XmDIALOG_SEPARATOR));
  1718.     XtUnmanageChild(XmSelectionBoxGetChild (dialog, XmDIALOG_TEXT));
  1719.     XtUnmanageChild (XmSelectionBoxGetChild (dialog,
  1720.                                              XmDIALOG_SELECTION_LABEL));
  1721.     XtUnmanageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_APPLY_BUTTON));
  1722. #ifdef NO_HELP
  1723.     XtUnmanageChild(XmSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
  1724. #endif
  1725.  
  1726.     XtAddCallback (dialog, XmNokCallback, fe_helpers_done_cb, fep);
  1727.     XtAddCallback (dialog, XmNcancelCallback, fe_helpers_cancel_cb, fep);
  1728.     XtAddCallback (dialog, XmNdestroyCallback, fe_helpers_destroy_cb, fep);
  1729.  
  1730.     ac = 0;
  1731.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  1732.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  1733.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1734.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1735.     form = XmCreateForm (dialog, "helperEdit", av, ac);
  1736.     XtManageChild (form);
  1737.  
  1738.     ac = 0;
  1739.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1740.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1741.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  1742.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
  1743.     form1 = XmCreateForm (form, "helperEditForm", av, ac);
  1744.  
  1745.     ac = 0;
  1746.     i = 0;
  1747.     kids[i++] = mime_types_desc_label= XmCreateLabelGadget (form1,
  1748.                                                             "mimeTypesDescriptionLabel", av, ac);
  1749.     kids[i++] = mime_types_desc_text = fe_CreateTextField (form1,
  1750.                                                            "mimeTypesDescriptionText",av,ac);
  1751.     kids[i++] = mime_types_label = XmCreateLabelGadget (form1,
  1752.                                                         "mimeTypesLabel", av, ac);
  1753.     kids[i++] = mime_types_text = fe_CreateTextField (form1,
  1754.                                                       "mimeTypesText",av,ac);
  1755.     kids[i++] = mime_types_suffix_label = XmCreateLabelGadget (form1,
  1756.                                                                "mimeTypesSuffixLabel", av, ac);
  1757.     kids[i++] = mime_types_suffix_text = fe_CreateTextField (form1,
  1758.                                                              "mimeTypesSuffixText",av,ac);
  1759.  
  1760.  
  1761.     if (fe_globalData.nonterminal_text_translations)
  1762.       {
  1763.         XtOverrideTranslations (mime_types_desc_text,
  1764.                                 fe_globalData.nonterminal_text_translations);
  1765.         XtOverrideTranslations (mime_types_text,
  1766.                                 fe_globalData.nonterminal_text_translations);
  1767.       }
  1768.  
  1769.     XtAddCallback(mime_types_text,  XmNvalueChangedCallback,
  1770.                   fe_helpers_set_handle_by_cb, fep);
  1771.  
  1772.     /* Layout the helper editor widgets in the form1 */
  1773.     XtVaSetValues (mime_types_desc_label,
  1774.                    XmNalignment, XmALIGNMENT_END,
  1775.                    XmNtopAttachment, XmATTACH_FORM,
  1776.                    XmNbottomAttachment, XmATTACH_NONE,
  1777.                    XmNleftAttachment, XmATTACH_FORM,
  1778.                    XmNrightAttachment, XmATTACH_NONE,
  1779.                    0);
  1780.     XtVaSetValues (mime_types_desc_text,
  1781.                    XmNtopAttachment, XmATTACH_FORM,
  1782.                    XmNbottomAttachment, XmATTACH_NONE,
  1783.                    XmNleftAttachment, XmATTACH_WIDGET,
  1784.                    XmNleftWidget,    mime_types_desc_label,
  1785.                    XmNrightAttachment, XmATTACH_FORM,
  1786.                    0);
  1787.  
  1788.     XtVaSetValues(mime_types_desc_label, XmNheight, 
  1789.                   XfeHeight(mime_types_desc_text),0);
  1790.  
  1791.     XtVaSetValues (mime_types_label,
  1792.                    XmNalignment, XmALIGNMENT_END,
  1793.                    XmNtopAttachment, XmATTACH_WIDGET,
  1794.                    XmNtopWidget, mime_types_desc_label,
  1795.                    XmNbottomAttachment, XmATTACH_NONE,
  1796.                    XmNleftAttachment, XmATTACH_FORM,
  1797.                    XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
  1798.                    XmNrightWidget, mime_types_desc_label,
  1799.                    0);
  1800.  
  1801.     XtVaSetValues (mime_types_text,
  1802.                    XmNtopAttachment, XmATTACH_WIDGET,
  1803.                    XmNtopWidget,mime_types_desc_text ,
  1804.                    XmNbottomAttachment, XmATTACH_NONE,
  1805.                    XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
  1806.                    XmNleftWidget, mime_types_desc_text,
  1807.                    XmNrightAttachment, XmATTACH_FORM,
  1808.                    0);
  1809.  
  1810.     XtVaSetValues(mime_types_label, XmNheight, 
  1811.                   XfeHeight(mime_types_text), 0);
  1812.  
  1813.     XtVaSetValues (mime_types_suffix_label,
  1814.                    XmNalignment, XmALIGNMENT_END,
  1815.                    XmNtopAttachment, XmATTACH_WIDGET,
  1816.                    XmNtopWidget, mime_types_label,
  1817.                    XmNbottomAttachment, XmATTACH_NONE,
  1818.                    XmNleftAttachment, XmATTACH_FORM,
  1819.                    XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
  1820.                    XmNrightWidget, mime_types_label,
  1821.                    0);
  1822.  
  1823.     XtVaSetValues (mime_types_suffix_text,
  1824.                    XmNtopAttachment, XmATTACH_WIDGET,
  1825.                    XmNtopWidget, mime_types_text,
  1826.                    XmNbottomAttachment, XmATTACH_NONE,
  1827.                    XmNleftAttachment, XmATTACH_WIDGET,
  1828.                    XmNleftWidget, mime_types_suffix_label,
  1829.                    XmNrightAttachment, XmATTACH_FORM,
  1830.                    0);
  1831.  
  1832.     XtVaSetValues(mime_types_suffix_label, XmNheight, 
  1833.                   XfeHeight(mime_types_suffix_text), 0);
  1834.  
  1835.  
  1836.     XtManageChildren(kids,i);
  1837.     XtManageChild(form1);
  1838.  
  1839.  
  1840.     ac = 0;
  1841.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1842.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1843.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  1844.     XtSetArg (av [ac], XmNtopWidget, form1); ac++;
  1845.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  1846.     frame1 = XmCreateFrame (form, "helperEditFrame", av, ac);
  1847.     ac = 0;
  1848.     XtSetArg (av [ac], XmNchildType, XmFRAME_TITLE_CHILD); ac++;
  1849.     label1 = XmCreateLabelGadget (frame1, "helperEditFrameLabel", av, ac);
  1850.  
  1851.     ac = 0;
  1852.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1853.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1854.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  1855.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  1856.     form2 = XmCreateForm (frame1, "helperEditHandleBox", av, ac);
  1857.  
  1858.     ac = 0;
  1859.     i = 0;
  1860.     kids [i++] = navigator_b = XmCreateToggleButtonGadget (form2,
  1861.                                                            "helperEditNavigator", av,ac);
  1862.     kids [i++] = plugin_b = XmCreateToggleButtonGadget (form2,
  1863.                                                         "helperEditPlugin", av,ac);
  1864.  
  1865.  
  1866.     ac = 0;
  1867.     XtSetArg (av[ac], XmNvisual, v); ac++;
  1868.     XtSetArg (av[ac], XmNdepth, depth); ac++;
  1869.     XtSetArg (av[ac], XmNcolormap, cmap); ac++;
  1870.     plugin_pulldown = XmCreatePulldownMenu (form2, "pluginPullDown", av, ac);
  1871.  
  1872.     ac = 0;
  1873.     XtSetArg(av[ac], XmNsubMenuId, plugin_pulldown); ac++;
  1874.     kids [i++] = plugin_option = fe_CreateOptionMenu (form2,"pluginMenu", av, ac);
  1875.  
  1876.     kids [i++] = app_b = XmCreateToggleButtonGadget (form2,
  1877.                                                      "helperEditApp", av,ac);
  1878.     kids [i++] = app_text = fe_CreateTextField (form2,
  1879.                                                 "helperEditAppText", av,ac);
  1880.     kids [i++] = app_browse = XmCreatePushButton (form2,
  1881.                                                   "helperEditAppBrowse", av,ac);
  1882.     kids [i++] = save_b = XmCreateToggleButtonGadget (form2,
  1883.                                                       "helperEditSave", av,ac);
  1884.     kids [i++] = unknown_b = XmCreateToggleButtonGadget (form2,
  1885.                                                          "helperEditUnknown", av,ac);
  1886.  
  1887.     fep->mime_types_desc_text = mime_types_desc_text;
  1888.     fep->mime_types_text = mime_types_text;
  1889.     fep->mime_types_suffix_text = mime_types_suffix_text;
  1890.     fep->navigator_b = navigator_b;
  1891.     fep->plugin_b    = plugin_b;
  1892.     fep->app_b       = app_b;
  1893.     fep->app_text    = app_text;
  1894.     fep->app_browse  = app_browse;
  1895.     fep->save_b      = save_b;
  1896.     fep->unknown_b   = unknown_b;
  1897.     fep->plugin_option = plugin_option;
  1898.     fep->plugin_pulldown = plugin_pulldown;
  1899.   
  1900.     fe_helpers_build_plugin_list(fep, (fep->cd ? fep->cd->ci.type:NULL));
  1901.   
  1902.     XtVaSetValues (navigator_b,
  1903.                    XmNtopAttachment, XmATTACH_FORM,
  1904.                    XmNbottomAttachment, XmATTACH_NONE,
  1905.                    XmNleftAttachment, XmATTACH_FORM,
  1906.                    XmNrightAttachment, XmATTACH_NONE,
  1907.                    XmNsensitive, True,
  1908.                    0);
  1909.  
  1910.     XtVaSetValues (plugin_b,
  1911.                    XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  1912.                    XmNtopWidget, plugin_option,
  1913.                    XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
  1914.                    XmNbottomWidget, plugin_option,
  1915.                    XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
  1916.                    XmNleftWidget, navigator_b,
  1917.                    XmNrightAttachment, XmATTACH_NONE,
  1918.                    0);
  1919.  
  1920.     XtVaSetValues (plugin_option,
  1921.                    XmNtopAttachment, XmATTACH_WIDGET,
  1922.                    XmNtopWidget, navigator_b,
  1923.                    XmNbottomAttachment, XmATTACH_NONE,
  1924.                    XmNleftAttachment, XmATTACH_FORM,
  1925.                    XmNleftOffset, XfeWidth(plugin_b) + 20,
  1926.                    XmNrightAttachment, XmATTACH_FORM,
  1927.                    0);
  1928.  
  1929.     XtVaSetValues (app_b,
  1930.                    XmNtopAttachment, XmATTACH_WIDGET,
  1931.                    XmNtopWidget, plugin_option,
  1932.                    XmNbottomAttachment, XmATTACH_NONE,
  1933.                    XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
  1934.                    XmNleftWidget, plugin_b,
  1935.                    XmNrightAttachment, XmATTACH_NONE,
  1936.                    0);
  1937.  
  1938.     XtVaGetValues( app_b, XmNindicatorSize, &size, 
  1939.                    XmNspacing, &space, 0 );
  1940.  
  1941.     XtVaSetValues (app_text,
  1942.                    XmNsensitive, False,
  1943.                    XmNtopAttachment, XmATTACH_WIDGET,
  1944.                    XmNtopWidget, app_b,
  1945.                    XmNbottomAttachment, XmATTACH_NONE,
  1946.                    XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
  1947.                    XmNleftWidget, plugin_b,
  1948.                    XmNleftOffset, size+space,
  1949.                    XmNrightAttachment, XmATTACH_FORM,
  1950.                    XmNrightOffset, XfeWidth(app_browse) + 10,
  1951.                    0);
  1952.  
  1953.     XtVaSetValues (app_browse,
  1954.                    XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  1955.                    XmNtopWidget, app_text,
  1956.                    XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
  1957.                    XmNbottomWidget, app_text,
  1958.                    XmNleftAttachment, XmATTACH_NONE,
  1959.                    XmNrightAttachment, XmATTACH_FORM,
  1960.                    0);
  1961.  
  1962.     XtVaSetValues (save_b,
  1963.                    XmNtopAttachment, XmATTACH_WIDGET,
  1964.                    XmNtopWidget, app_text,
  1965.                    XmNbottomAttachment, XmATTACH_NONE,
  1966.                    XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
  1967.                    XmNleftWidget, app_b,
  1968.                    XmNrightAttachment, XmATTACH_NONE,
  1969.                    0);
  1970.  
  1971.  
  1972.     XtVaSetValues (unknown_b,
  1973.                    XmNtopAttachment, XmATTACH_WIDGET,
  1974.                    XmNtopWidget, save_b,
  1975.                    XmNbottomAttachment, XmATTACH_NONE,
  1976.                    XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
  1977.                    XmNleftWidget, save_b,
  1978.                    XmNrightAttachment, XmATTACH_NONE,
  1979.                    0);
  1980.  
  1981.     XtAddCallback(navigator_b,  XmNvalueChangedCallback,
  1982.                   fe_helpers_verify_toggle_cb, fep);
  1983.     XtAddCallback(plugin_b,  XmNvalueChangedCallback,
  1984.                   fe_helpers_verify_toggle_cb, fep);
  1985.     XtAddCallback(app_b,  XmNvalueChangedCallback,
  1986.                   fe_helpers_verify_toggle_cb, fep);
  1987.     XtAddCallback(save_b,  XmNvalueChangedCallback,
  1988.                   fe_helpers_verify_toggle_cb, fep);
  1989.     XtAddCallback(unknown_b,  XmNvalueChangedCallback,
  1990.                   fe_helpers_verify_toggle_cb, fep);
  1991.  
  1992.     XtAddCallback(app_browse,  XmNactivateCallback,
  1993.                   fe_helpers_application_browse_cb, fep);
  1994.  
  1995.  
  1996.     XtManageChildren (kids, i);
  1997.     XtManageChild(form2);
  1998.     XtManageChild(label1);
  1999.     XtManageChild(frame1);
  2000.     XtManageChild(form);
  2001.  
  2002.     return dialog;
  2003. }
  2004.  
  2005. static void
  2006. fe_helpers_application_browse_cb(Widget widget, XtPointer closure,
  2007.                                  XtPointer call_data)
  2008. {
  2009.     struct fe_prefs_helpers_data *fep =  (struct fe_prefs_helpers_data *) closure;
  2010.     fe_browse_file_of_text (fep->context, fep->app_text, False);
  2011. }
  2012.  
  2013. static Bool
  2014. fe_helpers_handle_by_netscape(char *type)
  2015. {
  2016.     Bool rightType = False;
  2017.     if (!strcmp(type, TEXT_HTML) ||
  2018.         !strcmp(type, TEXT_MDL)||
  2019.         !strcmp(type, TEXT_PLAIN)||
  2020.         !strcmp(type, IMAGE_GIF) ||
  2021.         !strcmp(type, IMAGE_JPG) ||
  2022.         !strcmp(type, IMAGE_PJPG) ||
  2023.         !strcmp(type, IMAGE_XBM) ||
  2024.         !strcmp(type, IMAGE_XBM2) ||
  2025.         !strcmp(type, IMAGE_XBM3) ||
  2026.         !strcmp(type, APPLICATION_PRE_ENCRYPTED) ||
  2027.         !strcmp(type, APPLICATION_NS_PROXY_AUTOCONFIG)
  2028.         )
  2029.      
  2030.       {
  2031.         rightType = True;
  2032.       }
  2033.     return rightType;
  2034. }
  2035. static Bool
  2036. fe_helpers_handle_by_saveToDisk(char *type)
  2037. {
  2038.     Bool rightType = False;
  2039.     if ( !strcmp(type, APPLICATION_OCTET_STREAM) )
  2040.         rightType = True;
  2041.  
  2042.     return rightType;
  2043. }
  2044.  
  2045. static XP_Bool
  2046. fe_helpers_handle_by_plugin(struct fe_prefs_helpers_data *fep, char *type)
  2047. {
  2048.     Bool b;
  2049.     /* Create plugins options menu and sensitize the plugin option menu and
  2050.        toggle button, depending on the mimetype passed in */
  2051.  
  2052.     fe_helpers_build_plugin_list(fep, type);
  2053.     XtVaGetValues(fep->plugin_b, XmNsensitive, &b, 0);
  2054.     return(b);
  2055. }
  2056.  
  2057. static void
  2058. fe_helpers_set_handle_by_flag ( struct fe_prefs_helpers_data *fep, 
  2059.                                 NET_cdataStruct *cd)
  2060. {
  2061.     NET_mdataStruct *md = NULL;
  2062.   
  2063.     XtVaSetValues(fep->navigator_b, XmNsensitive, False, 0);
  2064.     /* Netscape Type ?*/
  2065.  
  2066.     if (fe_helpers_handle_by_netscape(cd->ci.type) )
  2067.       {
  2068.         XtVaSetValues(fep->navigator_b, XmNsensitive, True, 0);
  2069.       }
  2070.  
  2071.     md = fe_helpers_get_mailcap_from_type(cd->ci.type);
  2072.  
  2073.     if ( md && md->command && *md->command )
  2074.       {
  2075.         XtVaSetValues(fep->app_text, XmNsensitive, False, 0 );
  2076.         fe_SetTextField(fep->app_text, md->command);
  2077.       }
  2078.     
  2079.     if (md && md->xmode && *md->xmode)
  2080.       {
  2081.         md->xmode = fe_StringTrim(md->xmode);
  2082.  
  2083.         if (!strcmp(md->xmode, NET_COMMAND_UNKNOWN))
  2084.             XtVaSetValues(fep->unknown_b, XmNset, True, 0 );
  2085.         else if (fe_IsMailcapEntryPlugin(md))
  2086.             XtVaSetValues(fep->plugin_b, XmNset, True, 0 );
  2087.         else if (!strcmp(md->xmode, NET_COMMAND_SAVE_TO_DISK) ||
  2088.                  (!strcmp(md->xmode, NET_COMMAND_SAVE_BY_NETSCAPE)))
  2089.             XtVaSetValues(fep->save_b, XmNset, True, 0 );
  2090.         else if (!strcmp(md->xmode,NET_COMMAND_NETSCAPE))
  2091.             XtVaSetValues(fep->navigator_b, XmNset, True, 0 );
  2092.         else if (!strcmp(md->xmode,NET_COMMAND_DELETED))
  2093.             XtVaSetValues(fep->unknown_b, XmNset, True, 0 );
  2094.       }
  2095.     else if ( md  && md->command && *md->command)
  2096.       {
  2097.         XtVaSetValues(fep->app_b, XmNset, True, 0 );
  2098.         XtVaSetValues(fep->app_text,
  2099.                       XmNsensitive, True, 0 );
  2100.       }
  2101.     else if (fe_helpers_handle_by_netscape(cd->ci.type) )
  2102.         XtVaSetValues(fep->navigator_b, XmNset, True, 0 );
  2103.     else if (fe_helpers_handle_by_saveToDisk(cd->ci.type) )
  2104.         XtVaSetValues(fep->save_b, XmNset, True, 0 );
  2105.     else
  2106.         XtVaSetValues(fep->unknown_b, XmNset, True, 0);
  2107. }
  2108.  
  2109. static void 
  2110. fe_helpers_set_handle_by_cb (Widget w, XtPointer closure, XtPointer call_data )
  2111. {
  2112.     struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure;
  2113.     char *text = NULL;
  2114.     Bool nav_p = False, plugin_p = False;
  2115.  
  2116.     text = fe_GetTextField(fep->mime_types_text);
  2117.  
  2118.     if (text && *text && fe_helpers_handle_by_netscape(text)) {
  2119.       XtVaSetValues(fep->navigator_b, XmNsensitive, True, 0);
  2120.       nav_p = True;
  2121.     }
  2122.     else
  2123.         XtVaSetValues(fep->navigator_b, XmNsensitive, False, 0);
  2124.  
  2125.     if (text && *text && fe_helpers_handle_by_plugin(fep, text))
  2126.         /* fe_helpers_handle_by_plugin() will sensitize the plugin button. */
  2127.         plugin_p = True;
  2128.   
  2129.     /* if Navigator used to handle this but cannot anymore, unknown takes over */
  2130.     if (XmToggleButtonGetState(fep->navigator_b) && !nav_p)
  2131.         XmToggleButtonSetState(fep->unknown_b, True, True);
  2132.  
  2133.     /* if Plugin used to handle this but cannot anymore, unknown takes over */
  2134.     if (XmToggleButtonGetState(fep->plugin_b) && !plugin_p)
  2135.         XmToggleButtonSetState(fep->unknown_b, True, True);
  2136.  
  2137.     if (text) XP_FREE(text);
  2138.  
  2139. static void
  2140. fe_helpers_fill_edit_with_data(struct fe_prefs_helpers_data *fep,  
  2141.                                NET_cdataStruct *cd)
  2142. {
  2143.     int i;
  2144.     char *extensions = 0; /* has to initialize bf. passing to StrAllocCopy() */
  2145.  
  2146.     if ( !fep || !cd->ci.type || !*cd->ci.type ) return;
  2147.     /* Found Type */
  2148.     XtVaSetValues(fep->mime_types_text, XmNcursorPosition, 0, 0);
  2149.     fe_SetTextField(fep->mime_types_text, cd->ci.type);
  2150.  
  2151.     /* MIME Description */
  2152.     if ( cd->ci.desc && *cd->ci.desc ) {
  2153.         XtVaSetValues(fep->mime_types_desc_text, XmNcursorPosition, 0, 0 );
  2154.         fe_SetTextField(fep->mime_types_desc_text, cd->ci.desc);
  2155.     }
  2156.  
  2157.     /* MIME Suffix */
  2158.     for ( i = 0; i < cd->num_exts; i++ )
  2159.       {
  2160.         if ( i == 0 )
  2161.           {
  2162.             StrAllocCopy(extensions, cd->exts[i] );
  2163.           }
  2164.         else 
  2165.           {
  2166.             extensions = XP_AppendStr(extensions, ",");
  2167.             extensions = XP_AppendStr(extensions,  cd->exts[i]);
  2168.           }
  2169.       }
  2170.  
  2171.     if (cd->num_exts > 0 )
  2172.       {
  2173.         XtVaSetValues(fep->mime_types_suffix_text, XmNcursorPosition, 0, 0 );
  2174.         XtVaSetValues(fep->mime_types_suffix_text, extensions);
  2175.       }
  2176.  
  2177.     /* Handle By...this mail cap */
  2178.     fe_helpers_set_handle_by_flag(fep, cd);
  2179. }
  2180.  
  2181. static NET_cdataStruct *
  2182. fe_helpers_get_mime_data_at_pos(int pos) /* Starting from 0 */
  2183. {
  2184.     int count = 0;
  2185.     NET_cdataStruct *cd = NULL;
  2186.     XP_List *infoList = cinfo_MasterListPointer();
  2187.  
  2188.     while((cd = XP_ListNextObject(infoList)))
  2189.       {
  2190.         if ( cd->ci.type  && *cd->ci.type 
  2191.              && !fe_helpers_is_deleted_type(cd))
  2192.           {
  2193.             if ( pos == count ) 
  2194.               {
  2195.                 break;
  2196.               }
  2197.             else
  2198.                 count++;
  2199.           }
  2200.       }
  2201.  
  2202.     return cd;
  2203. }
  2204.  
  2205. static void
  2206. fe_helpers_edit_cb( Widget w, XtPointer closure, XtPointer call_data)
  2207. {
  2208.     NET_cdataStruct *cd = NULL;
  2209.     struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure;
  2210.     int    selectedCount;
  2211.     int    pos[1]; /* we are browse select, so only 1 row is selected */
  2212.  
  2213.     selectedCount = XmLGridGetSelectedRowCount(fep->helpers_list);
  2214.  
  2215.     if ( selectedCount != 1 )
  2216.         return;
  2217.  
  2218.     XmLGridGetSelectedRows(fep->helpers_list, pos, selectedCount);
  2219.  
  2220.     
  2221.     /* pos in the list always start from 0 */
  2222.     cd = fe_helpers_get_mime_data_at_pos(pos[0]);
  2223.     if ( fep )
  2224.       {
  2225.         fep->pos = pos[0];
  2226.         fep->cd = cd;
  2227.         fep->editor = fe_helpers_make_edit_dialog(fep);
  2228.         fe_helpers_fill_edit_with_data(fep, cd);
  2229.         XtManageChild(fep->editor);
  2230.       }
  2231.  
  2232. static void
  2233. fe_helpers_new_cb( Widget w, XtPointer closure, XtPointer call_data)
  2234. {
  2235.     struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure;
  2236.     if ( fep) 
  2237.       {
  2238.         fep->pos = 0;
  2239.         fep->editor = fe_helpers_make_edit_dialog(fep);
  2240.         fep->cd = NULL;
  2241.         XtManageChild(fep->editor);
  2242.       }
  2243.  
  2244. static void
  2245. fe_helpers_delete_cb( Widget w, XtPointer closure, XtPointer call_data)
  2246. {
  2247.     char *old_str = 0;
  2248.     char *src_str = 0;
  2249.     NET_cdataStruct* cd = NULL;
  2250.     NET_mdataStruct* old_md= NULL;
  2251.     struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure;
  2252.     int    selectedCount;
  2253.     int    pos[1]; /* we are browse select, so only 1 row is selected */
  2254.  
  2255.     selectedCount = XmLGridGetSelectedRowCount(fep->helpers_list);
  2256.  
  2257.     if ( selectedCount != 1 )
  2258.         return;
  2259.  
  2260.     XmLGridGetSelectedRows(fep->helpers_list, pos, selectedCount);
  2261.  
  2262.  
  2263.     /* pos in the list always start from 0 */
  2264.     cd = fe_helpers_get_mime_data_at_pos(pos[0]);
  2265.     if ( fep )
  2266.       {
  2267.         fep->pos = pos[0];
  2268.         fep->cd = cd;
  2269.  
  2270.  
  2271.         if (XFE_Confirm (fep->context, fe_globalData.helper_app_delete_message)) 
  2272.           {
  2273.             fe_MarkHelpersModified(fep->context);
  2274.  
  2275.             old_md = fe_helpers_get_mailcap_from_type(fep->cd->ci.type); 
  2276.  
  2277.             if ( old_md )  
  2278.               {
  2279.                 /* If there is a mailcap entry, 
  2280.                    then update to reflect delete */
  2281.                 old_str = old_md->src_string;
  2282.                 old_md->src_string = 0;
  2283.  
  2284.               }
  2285.             if ( !old_str || !strlen(old_str))
  2286.               {
  2287.                 src_str = fe_helpers_construct_new_mailcap_string(old_md, 
  2288.                                                                   fep->cd->ci.type, NULL, 
  2289.                                                                   NET_COMMAND_DELETED);
  2290.               }
  2291.             else
  2292.               {
  2293.     
  2294.                 src_str = fe_helpers_deleteCommand(old_str);
  2295.                 XP_FREE(old_str);
  2296.  
  2297.                 old_str = src_str;
  2298.                 src_str = fe_helpers_updateKey(src_str, NET_MOZILLA_FLAGS, 
  2299.                                                NET_COMMAND_DELETED, 1 );
  2300.                 XP_FREE(old_str);
  2301.               }
  2302.  
  2303.             if ( old_md )
  2304.               {
  2305.                 if (old_md->src_string ) XP_FREE(old_md->src_string);
  2306.                 old_md->src_string = 0;
  2307.  
  2308.                 if ( src_str && *src_str )
  2309.                     old_md->src_string = src_str;
  2310.  
  2311.                 if (old_md->xmode) XP_FREE(old_md->xmode);
  2312.                 old_md->xmode = strdup(NET_COMMAND_DELETED);
  2313.                 old_md->is_modified = 1;
  2314.               }
  2315.             else
  2316.               {
  2317.                 fe_helpers_add_new_mailcap_data(fep->cd->ci.type, 
  2318.                                                 src_str, NULL,  
  2319.                                                 NET_COMMAND_DELETED, 1);
  2320.                 XP_FREE(src_str);
  2321.               }
  2322.  
  2323.             XmLGridDeleteRows(fep->helpers_list, XmCONTENT, fep->pos, 1);
  2324.  
  2325.             if (fep->cd->is_new  ) 
  2326.               {
  2327.                 NET_cdataRemove(fep->cd);
  2328.                 if ( old_md )
  2329.                     NET_mdataRemove(old_md);
  2330.               }
  2331.             fep->cd = 0;
  2332.             fep->pos = 0;
  2333.           }
  2334.       }
  2335.  
  2336. static void
  2337. fe_helpers_add_list_row(struct fe_prefs_helpers_data *fep, char *data)
  2338. {
  2339.     int total ;
  2340.     XtVaGetValues( fep->helpers_list, XmNrows, &total, 0 );
  2341.     XmLGridAddRows(fep->helpers_list, XmCONTENT, -1, 1);
  2342.     if ( total > 0 )
  2343.         XmLGridMoveRows(fep->helpers_list, 1, 0, total);
  2344.     XmLGridSetStringsPos(fep->helpers_list, XmCONTENT, 0, 
  2345.                          XmCONTENT, 0, data);
  2346.  
  2347. static void
  2348. fe_helpers_append_list_row(struct fe_prefs_helpers_data *fep, int row, char *data)
  2349. {
  2350.     int total ;
  2351.     XtVaGetValues( fep->helpers_list, XmNrows, &total, 0 );
  2352.     if ( row >= total )
  2353.         XmLGridAddRows(fep->helpers_list, XmCONTENT, -1, 1);
  2354.  
  2355.     XmLGridSetStringsPos(fep->helpers_list, XmCONTENT, row, 
  2356.                          XmCONTENT, 0, data);
  2357.  
  2358.  
  2359. NET_mdataStruct *
  2360. fe_helpers_get_mailcap_from_type(char *type)
  2361. {
  2362.     NET_mdataStruct *md_item= NULL, *new_item = NULL;
  2363.     /* Get beginning of the list
  2364.      */
  2365.     XP_List *infolist = mailcap_MasterListPointer();
  2366.  
  2367.     while ((md_item = (NET_mdataStruct *)XP_ListNextObject(infolist)))
  2368.       {
  2369.         if ( type && md_item->contenttype &&
  2370.              !XP_STRCASECMP(type, md_item->contenttype))
  2371.           {
  2372.             new_item = md_item;
  2373.             break;
  2374.           }
  2375.       }
  2376.     return new_item;
  2377. }
  2378.  
  2379.  
  2380. static void
  2381. fe_helpers_append_type_to_list(struct fe_prefs_helpers_data *fep, NET_cdataStruct *cd_item, 
  2382.                                NET_mdataStruct *md,
  2383.                                int pos)
  2384. {
  2385.     char *desc = 0, *action = 0, *line = 0;
  2386.  
  2387.     if ( cd_item->ci.type && strlen(cd_item->ci.type) )
  2388.       {
  2389.         cd_item->ci.type = fe_StringTrim(cd_item->ci.type);
  2390.         StrAllocCopy( desc, cd_item->ci.type);
  2391.       }
  2392.  
  2393.     if ( md && md->xmode && *md->xmode )
  2394.       {
  2395.         if ( !XP_STRCASECMP(md->xmode, NET_COMMAND_NETSCAPE ))
  2396.             StrAllocCopy(action, XP_GetString(XFE_HELPERS_NETSCAPE));
  2397.         else if (!strcmp(md->xmode, NET_COMMAND_SAVE_TO_DISK) ||
  2398.                  (!strcmp(md->xmode, NET_COMMAND_SAVE_BY_NETSCAPE)))
  2399.             StrAllocCopy(action, XP_GetString(XFE_HELPERS_SAVE));
  2400.         else if ( !XP_STRCASECMP(md->xmode, NET_COMMAND_UNKNOWN ))
  2401.             StrAllocCopy(action, XP_GetString(XFE_HELPERS_UNKNOWN));
  2402.         else if (fe_IsMailcapEntryPlugin(md)) {
  2403.           char *pluginName = fe_GetPluginNameFromMailcapEntry(md);
  2404.           action = PR_smprintf(XP_GetString(XFE_HELPERS_PLUGIN),
  2405.                                pluginName);
  2406.         }
  2407.       }
  2408.     else if (md && md->command && *md->command)
  2409.       {
  2410.         md->command = fe_StringTrim(md->command);
  2411.         StrAllocCopy( action, md->command);
  2412.       }
  2413.     else if (fe_helpers_handle_by_netscape(cd_item->ci.type) )
  2414.         StrAllocCopy(action, XP_GetString(XFE_HELPERS_NETSCAPE));
  2415.     else if (fe_helpers_handle_by_saveToDisk(cd_item->ci.type))
  2416.         StrAllocCopy(action, XP_GetString(XFE_HELPERS_SAVE));
  2417.     else
  2418.         StrAllocCopy(action, XP_GetString(XFE_HELPERS_UNKNOWN));
  2419.  
  2420.     if ( desc && action )
  2421.       {
  2422.         line = PR_smprintf("%s|%s", desc, action); 
  2423.  
  2424.         if (pos <= 0)
  2425.             fe_helpers_add_list_row(fep, line);
  2426.         else 
  2427.             fe_helpers_append_list_row(fep, pos, line);
  2428.  
  2429.       }
  2430.     if (desc) XP_FREE(desc);
  2431.     if (action) XP_FREE(action);
  2432.     if (line) XP_FREE(line);
  2433. }
  2434.  
  2435. void
  2436. fe_helpers_build_mime_list(struct fe_prefs_helpers_data *fep)
  2437. {
  2438.     int item_count = 0;
  2439.     NET_mdataStruct *md;
  2440.     NET_cdataStruct *cd_item;
  2441.  
  2442.     /* Get beginning of the list */
  2443.     XP_List *infolist = cinfo_MasterListPointer();
  2444.     XtVaSetValues( fep->helpers_list, XmNlayoutFrozen, True, NULL);
  2445.  
  2446.     /* Get the file format from the object in order to
  2447.        build the Helpers  */
  2448.     while ((cd_item = (NET_cdataStruct *)XP_ListNextObject(infolist)))
  2449.       {
  2450.         if ( cd_item->ci.type  && (int)strlen(cd_item->ci.type) >0 )
  2451.           {
  2452.             /* Add this item to the list table */
  2453.             if ( !fe_helpers_is_deleted_type(cd_item) )
  2454.               {
  2455.                 md = fe_helpers_get_mailcap_from_type(cd_item->ci.type);
  2456.                 fe_helpers_append_type_to_list(fep, cd_item,md, item_count);
  2457.                 item_count++;
  2458.               }
  2459.           }
  2460.       }
  2461.     XtVaSetValues( fep->helpers_list, XmNlayoutFrozen, False, NULL);
  2462. }
  2463.  
  2464.  
  2465. struct fe_prefs_helpers_data *
  2466. fe_helpers_make_helpers_page (MWContext *context, Widget parent)
  2467. {
  2468.     Arg av [50];
  2469.     int ac;
  2470.     XmFontList fontList, labelFont/*, defaultLabelFont*/;
  2471.     short avgwidth, avgheight;
  2472.     Widget form, commands, table, b;
  2473.     Widget label1, frame1, form1;
  2474.     Dimension width;    
  2475.  
  2476.     /* Initialization */
  2477.     struct fe_prefs_helpers_data *fep = NULL; /* Helper data kept here */
  2478.  
  2479.     fep = (struct fe_prefs_helpers_data *) malloc (
  2480.                                                    sizeof (struct fe_prefs_helpers_data));
  2481.     memset (fep, 0, sizeof (struct fe_prefs_helpers_data));
  2482.  
  2483.     fep->context = context;
  2484.     fep->helpers_selector = parent;
  2485.  
  2486.     /* Create the enclosing form */
  2487.     ac = 0;
  2488.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  2489.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  2490.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  2491.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  2492.     XtSetArg (av [ac], XmNresizePolicy, XmNONE); ac++;
  2493.     form = XmCreateForm (fep->helpers_selector, "helpers", av, ac);
  2494.     XtManageChild (form);
  2495.     fep->helpers_page = form;
  2496.   
  2497.  
  2498.     /* Create the frame and form for the helper files */
  2499.     ac = 0;
  2500.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  2501.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  2502.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  2503.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  2504.     frame1 = XmCreateFrame (form, "helperFrame", av, ac);
  2505.     ac = 0;
  2506.     form1 = XmCreateForm (frame1, "helperBox", av, ac);
  2507.  
  2508.     /* Create labels */
  2509.     ac = 0;
  2510.     XtSetArg (av [ac], XmNchildType, XmFRAME_TITLE_CHILD); ac++;
  2511.     label1 = XmCreateLabelGadget (frame1, "helperBoxLabel", av, ac);
  2512.  
  2513.     XtVaGetValues(label1, XmNfontList, &labelFont, NULL);
  2514.  
  2515.     /* Create the widgets for the helper form */
  2516.  
  2517.     ac = 0;
  2518.     XtSetArg(av[ac], XmNselectionPolicy, XmSELECT_BROWSE_ROW); ac++;
  2519.     XtSetArg(av[ac], XmNhorizontalSizePolicy, XmCONSTANT); ac++;
  2520.     XtSetArg(av[ac], XmNallowColumnResize, True); ac++;
  2521.     XtSetArg(av[ac], XmNcolumnSizePolicy, XmVARIABLE); ac++;
  2522.     table = fep->helpers_list = XmLCreateGrid(form1, "helperApp", av, ac);
  2523.     XtVaSetValues( fep->helpers_list, XmNlayoutFrozen, True, NULL);
  2524.  
  2525.     XmLGridAddColumns(fep->helpers_list, XmCONTENT, -1, 2 );
  2526.  
  2527.     XtVaSetValues(fep->helpers_list, 
  2528.                   XmNrowType, XmHEADING,
  2529.                   XmNcolumn, 0,
  2530.                   XmNcellDefaults, True,
  2531.                   /*        XmNcellFontList, labelFont, */
  2532.                   XmNcolumnWidth,  DEFAULT_COLUMN_WIDTH,
  2533.                           XmNcellType, XmSTRING_CELL,
  2534.                           XmNcellEditable, True,
  2535.                   XmNcellAlignment, XmALIGNMENT_LEFT, NULL);
  2536.  
  2537.  
  2538.     /* Second Column */
  2539.     XtVaSetValues(fep->helpers_list, 
  2540.                   XmNrowType, XmHEADING,
  2541.                   XmNcolumn, 1,
  2542.                   XmNcellDefaults, True,
  2543.                   /*        XmNcellFontList, labelFont, */
  2544.                           XmNcellType, XmSTRING_CELL,
  2545.                             XmNcellEditable, True,
  2546.                   XmNcolumnWidth, MAX_COLUMN_WIDTH,
  2547.                   XmNcellAlignment, XmALIGNMENT_LEFT, NULL);
  2548.  
  2549.     XmLGridAddRows(fep->helpers_list, XmHEADING, -1, 1);
  2550.     XmLGridSetStrings(fep->helpers_list, XP_GetString(XFE_HELPERS_LIST_HEADER));
  2551.  
  2552.  
  2553.     /* Get the font from *XmLGrid*fontList at this point.  - XXX dp */
  2554.     /* defaultLabelFont = fe_GetFont (context, 2, LO_FONT_FIXED); */
  2555.  
  2556.     XtVaSetValues(fep->helpers_list, XmNcellDefaults, True,
  2557.                   XmNcellType, XmSTRING_CELL,
  2558.                   XmNcellEditable, False,
  2559.                   /*        XmNcellFontList, (defaultLabelFont? defaultLabelFont: NULL), */
  2560.                   XmNcellLeftBorderType, XmBORDER_NONE,
  2561.                   XmNcellRightBorderType, XmBORDER_NONE,
  2562.                   XmNcellTopBorderType, XmBORDER_NONE,
  2563.                   XmNcellBottomBorderType, XmBORDER_NONE,
  2564.                   XmNcellAlignment, XmALIGNMENT_LEFT, NULL);
  2565.  
  2566.     XtVaSetValues(fep->helpers_list, XmNlayoutFrozen, False, NULL);
  2567.  
  2568.  
  2569.     /* Create for Edit..., New, Delete Buttons */
  2570.  
  2571.     ac = 0;
  2572.     XtSetArg (av [ac], XmNskipAdjust, True); ac++;
  2573.     XtSetArg (av [ac], XmNorientation, XmVERTICAL); ac++;
  2574.     XtSetArg (av [ac], XmNpacking, XmPACK_TIGHT); ac++;
  2575.     commands = XmCreateRowColumn(form1, "commands",  av, ac);
  2576.  
  2577.     ac = 0;
  2578.     fep->edit_b = b = XmCreatePushButton(commands, "edit", av, ac);
  2579.     XtAddCallback(b, XmNactivateCallback, fe_helpers_edit_cb, fep);
  2580.     XtManageChild(b);
  2581.  
  2582.     ac = 0;
  2583.     fep->new_b = b = XmCreatePushButton(commands, "new", av, ac);
  2584.     XtAddCallback(b, XmNactivateCallback, fe_helpers_new_cb, fep);
  2585.     XtManageChild(b);
  2586.  
  2587.     ac = 0;
  2588.     fep->delete_b = b = XmCreatePushButton(commands, "delete", av, ac);
  2589.     XtAddCallback(b, XmNactivateCallback, fe_helpers_delete_cb, fep);
  2590.     XtManageChild(b);
  2591.  
  2592.     XtVaSetValues(commands, XmNleftAttachment, XmATTACH_NONE,
  2593.                   XmNrightAttachment, XmATTACH_FORM,
  2594.                   XmNbottomAttachment, XmATTACH_FORM,
  2595.                   XmNtopAttachment, XmATTACH_FORM,
  2596.                   NULL);
  2597.  
  2598.     XtVaSetValues(fep->helpers_list, XmNleftAttachment, XmATTACH_FORM,
  2599.                   XmNrightAttachment, XmATTACH_WIDGET,
  2600.                   XmNrightWidget, commands,
  2601.                   XmNbottomAttachment, XmATTACH_FORM,
  2602.                   XmNtopAttachment, XmATTACH_FORM,
  2603.                   NULL);
  2604.  
  2605.     XtManageChild(commands);
  2606.  
  2607.     /* Finally, manage the widgets in form1 */
  2608.     XtManageChild(fep->helpers_list);
  2609.     XtManageChild (form1);
  2610.     XtManageChild (label1);
  2611.     XtManageChild(frame1);
  2612.     XtManageChild(form);
  2613.  
  2614.     /* Set up Column Width */
  2615.     XtVaGetValues(fep->helpers_list, XmNfontList, &fontList, XmNwidth, &width, NULL);
  2616.     XmLFontListGetDimensions(fontList, &avgwidth, &avgheight, TRUE);
  2617.  
  2618.     return fep;
  2619. }
  2620.  
  2621. /*
  2622.  * fe_helpers_prepareForDestroy()
  2623.  *
  2624.  * When the prefs is going to destroy the helpers and free the fep, prefs
  2625.  * will call this. The purpose of this is to take the neccessary steps to
  2626.  *        - free any internal data
  2627.  *        - remove destroy callback that will access the fep
  2628.  */
  2629. void
  2630. fe_helpers_prepareForDestroy(struct fe_prefs_helpers_data *fep)
  2631. {
  2632.     /* If the edit dialog was up, then the destroy of pref will result in the
  2633.      * destroy of the edit dialog, that would inturn access the fep.
  2634.      * Prevent that.
  2635.      */
  2636.     if (fep->editor) {
  2637.         /* Prevent destroy from accessing the fep as it will be freed */
  2638.         XtRemoveCallback (fep->editor, XmNdestroyCallback,
  2639.                           fe_helpers_destroy_cb, fep);
  2640.  
  2641.         /* Do whatever destroy of the helper edit dialog does like
  2642.          * freeing memory ect
  2643.          */
  2644.         fe_helpers_destroy_cb(0, (XtPointer) fep, 0);
  2645.     }
  2646.     return;
  2647. }
  2648.