/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ /* pref_helpers.c --- Preference->Helper dialogs. Created: Dora Hsu , 25-Mar-96. */ #include "mozilla.h" #include "xlate.h" #include "xfe.h" #include "nslocks.h" #include "secnav.h" #include "mozjava.h" #include "prnetdb.h" #include "e_kit.h" #include "pref_helpers.h" #include "np.h" #include #include #include "felocale.h" #ifndef _STDC_ #define _STDC_ 1 #define HACKED_STDC 1 #endif #include #include #ifdef HACKED_STDC #undef HACKED_STDC #undef _STDC_ #endif #include "msgcom.h" /* for XP_GetString() */ #include extern int XFE_NO_PLUGINS; extern int XFE_HELPERS_NETSCAPE; extern int XFE_HELPERS_UNKNOWN; extern int XFE_HELPERS_SAVE; extern int XFE_HELPERS_PLUGIN; extern int XFE_HELPERS_EMPTY_MIMETYPE; extern int XFE_HELPERS_LIST_HEADER; extern int XFE_HELPERS_PLUGIN_DESC_CHANGE; #define DEFAULT_COLUMN_WIDTH 35 #define MAX_COLUMN_WIDTH 100 #define FE_MOZILLA_MIME_COMMENT "#mime types added by Netscape Helper" #define FE_MOZILLA_MAILCAP_COMMENT "#mailcap entry added by Netscape Helper" #define TYPE "type" #define DESC "desc" #define ENC "enc" #define ICON "icon" #define LANG "lang" #define EXTS "exts" #define ALT "alt" #define SPACE " " /* For sys_errlist and sys_nerr */ #include "prprf.h" #include "libi18n.h" #include "fonts.h" /* External Methods */ void fe_browse_file_of_text (MWContext *context, Widget text_field, Boolean dirp); void fe_UnmanageChild_safe (Widget w); /* From prefdialogs.c */ void fe_MarkHelpersModified(MWContext *context); /* Internal Methods */ static void fe_helpers_application_browse_cb(Widget widget, XtPointer closure, XtPointer call_data); static void fe_helpers_set_handle_by_cb (Widget w, XtPointer closure, XtPointer call_data ); static void fe_helpers_append_type_to_list(struct fe_prefs_helpers_data *fep, NET_cdataStruct *cd_item, NET_mdataStruct *md, int pos); /*===================== A pile of string manipulation=======================*/ static int /* returns len of token */ fe_GetToken (char *mess, char *token, int *n) /* n: next position to search*/ { int len, i, j; if (mess == NULL) return(0); if (*n > (int)strlen(mess)) return(0); i = *n; len = strspn(mess+i, " =;\\\t\n\0"); i += len; j = i; if (mess[i] == '"') { i++; j++; for (len = 0; mess[j] != '\n' && mess[j++] != '"'; len++); } else len = strcspn(mess+i, " =;\\\t\n\0"); strncpy(token, mess+i, len); token[len] = '\0'; if (j > 0 && mess[j-1] == '"') i++; *n = i + len; return(len); } static char* fe_helpers_appendKey (char *buf, char *key, char *val, Boolean hasSep) { char *newbuf=NULL; char str[80]; int len, i; /* validate inputs here */ if (!buf || !key || !val || !strlen(buf) || !strlen(key) || !strlen(val)) return NULL; if (hasSep) sprintf(str, "; \\\n%s=%s", key, val); else sprintf(str, " \\\n%s=%s", key, val); len = strlen(buf); for (i = len-1; buf[i] == '\n' || buf[i] == '\\' || buf[i] == ' ' || buf[i] == '\t'; i--); i++; len = strlen(buf) + strlen(str) + 1 + 1; newbuf = (char *)malloc(len); memset (newbuf, 0, len); strncpy (newbuf, buf, i); /* i-1 */ newbuf[i] = 0; if (newbuf[i-1] == ';') newbuf[i-1] = 0; strcat (newbuf, str); return(newbuf); } /*---------------------------------------------------------- -----------------------------------------------------------*/ static char* cleanString(char *newbuf ) { int i = 0; int found = 0; while (!found && (int)strlen(newbuf) > 0) { if ( newbuf[strlen(newbuf)-1] == ' ' || newbuf[strlen(newbuf)-1] == '\\' || newbuf[strlen(newbuf)-1] == ';' || newbuf[strlen(newbuf)-1] == '\n' || newbuf[strlen(newbuf)-1] == '\t' ) { newbuf[strlen(newbuf)-1] = '\0'; } else found = 1; } found = 0; i = 0; while (!found && (int)strlen(newbuf) > 0 && i < (int)strlen(newbuf)) { if ( newbuf[i] == '\\' || newbuf[i] == ';' ) { strncpy( newbuf, newbuf+i+1, strlen(newbuf)-i); } else found = 1; i++; } return newbuf; } static char* fe_helpers_deleteKey (char *buf, char *key, Boolean hasSep) { char *newbuf=NULL; char tok[80]; int len, i, j = 0, k = 0, n; int found = 0; int quote = 0; /* validate inputs here */ if (!buf || !key || !strlen(buf) || !strlen(key)) return NULL; len = strlen(buf); i = 0; while (!found && i < len) { j = i; n = fe_GetToken(buf, tok, &i); if (strcmp(tok, key) == 0) { n = strspn(buf+i, " \t\n"); i += n; if (buf[i] == '=') { n = strspn(buf+i, " =\"\t\n"); if ( buf[i+n-1] == '\"') quote = 1; k = i + n; if (hasSep) len = strcspn (buf+k, ";"); else { if ( quote ) { n = strcspn(buf+k, "\""); /* end quote*/ if ( buf[k+n] == '\"') k = k + n; quote = 0; } len = strcspn (buf+k, " \t\\"); } i = k + len; found = 1; } } else { n = strspn(buf+i, " ;\\\t\n"); i += n; } } if (found) { newbuf = strdup (buf); newbuf[j] = '\0'; found = 0; newbuf = cleanString(newbuf); strcat (newbuf, buf+i); newbuf = cleanString(newbuf); /* if( newbuf[strlen(newbuf)-1] != '\n' ) strcat(newbuf, "\n"); */ } return(newbuf); } /*---------------------------------------------------------- -----------------------------------------------------------*/ static char* fe_helpers_updateKey (char *buf, char *key, char *newVal, Boolean hasSep) { char *newbuf=NULL; char tok[80]; int len, i, k, n; int found = 0; int quote = 0; /* validate inputs here */ if (!buf || !key || !newVal || !strlen(buf) || !strlen(key) || !strlen(newVal)) return NULL; len = strlen(buf); i = 0; while (!found && i < len) { n = fe_GetToken(buf, tok, &i); if (strcmp(tok, key) == 0) { n = strspn(buf+i, " \t\n"); i += n; if (buf[i] == '=') { n = strspn(buf+i, " =\"\t\n"); if ( buf[i+n-1]== '\"') quote = 1; k = i + n; if (hasSep) len = strcspn (buf+k, ";"); else { if ( quote ) { len = strcspn(buf+k, "\""); /* end quote*/ quote = 0; } else len = strcspn (buf+k, " \t\\"); } strncpy(tok, buf+k, len); tok[len] = '\0'; i = k + len; found = 1; } } } if (found) { len = strlen(buf) - strlen(tok) + strlen(newVal) + 3; newbuf = (char *)malloc (len); memset (newbuf, 0, len); strncpy(newbuf, buf, k); newbuf[k] = 0; if (tok[0] == '"') strcat (newbuf, "\""); strcat (newbuf, newVal); if (tok[0] == '"') strcat (newbuf, "\""); strcat (newbuf, buf+i); } return(newbuf); } /*---------------------------------------------------------- -----------------------------------------------------------*/ static char* fe_helpers_addCommand(char *buf, char *command) { char *newbuf=0; int len, i, n, j; /* validate inputs here */ if (!buf || !command || !strlen(buf) || !strlen(command)) return 0; len = strlen(buf) + strlen(command) + strlen(";") * 2 + strlen("\n") + 1; j = strlen(buf); newbuf = (char *)malloc (len); memset(newbuf, '\0', len); /* buf is the src string. Hence skip any comments that are preceding * the actual specification. Then find the place of the ';'. */ n = 0; n += strspn(&buf[n], " \t\n"); while (buf[n] && buf[n] == '#') { n++; /* Skip until and including the newline */ while (buf[n] && buf[n] != '\n') n++; n += strspn(&buf[n], " \t\n"); } if (buf[n] == '\0') /* No entry. The entire entry was a comment. Punt. */ return(0); n += strcspn (&buf[n], ";"); /* find the ';' */ if ( buf[n] == ';' ) { j = n+1; if ( j < (int)strlen(buf) ) { i = strcspn (buf+j, ";"); /* find the second ";" */ /* If the second semicolon is missing, it is right for us * to assume its presence at the end. */ j = j+i+1; } } strncpy(newbuf, buf, n); newbuf[n] = '\0'; strcat (newbuf, ";"); strcat (newbuf, command); if (j < (int)strlen(buf)) /* more entries after command */ { strcat (newbuf, ";"); strcat (newbuf, buf + j); } /* strcat (newbuf, "\n"); */ return(newbuf); } static char* fe_helpers_deleteCommand(char *buf) { char *newbuf=0; int len, i, n, j; /* validate inputs here */ if (!buf || !strlen(buf)) return 0; len = strlen(buf) + 1; j = strlen(buf); newbuf = (char *)malloc (len); memset(newbuf, '\0', len); /* buf is the src string. Hence skip any comments that are preceding * the actual specification. Then find the place of the ';'. */ n = 0; n += strspn(&buf[n], " \t\n"); while (buf[n] && buf[n] == '#') { n++; /* Skip until and including the newline */ while (buf[n] && buf[n] != '\n') n++; n += strspn(&buf[n], " \t\n"); } if (buf[n] == '\0') /* No entry. The entire entry was a comment. Punt. */ return(0); n += strcspn (&buf[n], ";"); /* find the ';' */ if ( buf[n] == ';' ) { j = n+1; if ( j < (int)strlen(buf) ) { i = strcspn (buf+j, ";"); /* find the second ";" */ j = j +i; if ( j < (int)strlen(buf) && buf[j] == ';' ) j = j + 1; } } strncpy(newbuf, buf, n); newbuf[n] = '\0'; if (j < (int)strlen(buf)) /* more entries after command */ { strcat (newbuf, ";"); strcat (newbuf, ";"); strcat (newbuf, buf + j); } /* strcat (newbuf, "\n"); */ return newbuf; } /*======================== A pile of callbacks ========================*/ void fe_helpers_add_new_mailcap_data(char *contenttype, char* src_str, char *command, char *xmode, Boolean isLocal) { NET_mdataStruct *md = 0; md = NET_mdataCreate(); if ( md ) { md->contenttype = 0; md->command = 0; md->label = 0; md->testcommand = 0; md->printcommand = 0; md->stream_buffer_size = 0; md->xmode = 0; md->src_string = 0; md->is_modified = 1; md->is_local = isLocal; if ( contenttype && *contenttype ) StrAllocCopy(md->contenttype, contenttype ); if ( command && *command ) StrAllocCopy(md->command, command); if ( xmode && *xmode ) StrAllocCopy(md->xmode, xmode); if ( src_str && *src_str ) StrAllocCopy(md->src_string, src_str); NET_mdataAdd(md); } } static Boolean fe_helpers_is_deleted_type (NET_cdataStruct *cd_item) { NET_mdataStruct *md_item = 0; /* Check if this mime is deleted from the list */ md_item = fe_helpers_get_mailcap_from_type(cd_item->ci.type); if ( md_item && md_item->xmode && *md_item->xmode ) if ( !XP_STRCASECMP(md_item->xmode, NET_COMMAND_DELETED)) return True; else return False; else if (md_item && (!md_item->command|| !*md_item->command)) return True; return False; } static void fe_helpers_plugin_selected(struct fe_prefs_helpers_data *fep, char *pluginName) { /* Change the description and extensions to what the plugins says */ char *mimetype, *desc=NULL, *ext=NULL; char *cur_desc=NULL, *cur_ext=NULL; XP_Bool differ = True; mimetype = fe_GetTextField(fep->mime_types_text); if (fe_GetMimetypeInfoFromPlugin(pluginName, mimetype, &desc, &ext) >= 0) { /* If either the description or the extension is different from what is * already being displayed, ask the user whether to revert to what the * plugin says. */ cur_desc = fe_GetTextField(fep->mime_types_desc_text); cur_ext = fe_GetTextField(fep->mime_types_suffix_text); if (desc) differ = strcmp(desc, cur_desc); else differ = *cur_desc; if (!differ) if (ext) differ = strcmp(ext, cur_ext); else differ = *cur_ext; if (differ) { char *buf; buf = PR_smprintf(XP_GetString(XFE_HELPERS_PLUGIN_DESC_CHANGE), mimetype, desc?desc:"", ext?ext:""); if (FE_Confirm(fep->context, buf)) { XtVaSetValues(fep->mime_types_desc_text, XmNcursorPosition, 0, 0); fe_SetTextField(fep->mime_types_desc_text, desc); XtVaSetValues(fep->mime_types_suffix_text, XmNcursorPosition, 0, 0); fe_SetTextField(fep->mime_types_suffix_text, ext); } if (buf) XP_FREE(buf); } } if (mimetype) XP_FREE(mimetype); if (cur_desc) XP_FREE(cur_desc); if (cur_ext) XP_FREE(cur_ext); } static void fe_helpers_plugin_sel_cb(Widget widget, XtPointer closure, XtPointer call_data) { struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure; int n = 0; char *pluginName; if (!XmToggleButtonGetState(fep->plugin_b)) return; XtVaGetValues(widget, XmNuserData, &n, 0); pluginName = fep->plugins[n]; fe_helpers_plugin_selected(fep, pluginName); } static void fe_helpers_build_plugin_list(struct fe_prefs_helpers_data *fep, char *mime_type_to_find) { int i; Cardinal ac; Arg av[20]; Widget button = 0, current = 0; char namebuf[64]; char **plugins = NULL, *current_plugin = NULL; NET_mdataStruct *md = NULL; if (!fep) return; if (mime_type_to_find && *mime_type_to_find) plugins = NPL_FindPluginsForType(mime_type_to_find); /* Destroy all existing children */ if (fep->plugin_pulldown) { int nkids = 0; Widget *kids; XtVaGetValues(fep->plugin_pulldown, XmNchildren, &kids, XmNnumChildren, &nkids, 0); if (nkids > 0) { /* Conditions for not destroy are * 1. If we didn't have plugins previously and dont have any now * in all other cases, we destroy. */ if (nkids == 1 && !strcmp(XtName(kids[0]), "plugin0")) if (!plugins) return; XfeDestroyMenuWidgetTree(kids, nkids,False); } } if (plugins && plugins[0]) { md = fe_helpers_get_mailcap_from_type(mime_type_to_find); if (fe_IsMailcapEntryPlugin(md)) current_plugin = fe_GetPluginNameFromMailcapEntry(md); i = 0; while (plugins[i]) { sprintf(namebuf, "plugin%d", i+1); ac = 0; XtSetArg (av[ac], XmNuserData, i); ac++; button = XmCreatePushButtonGadget(fep->plugin_pulldown, namebuf, av, ac); fe_SetString(button, XmNlabelString, plugins[i]); XtAddCallback (button, XmNactivateCallback, fe_helpers_plugin_sel_cb, fep); XtManageChild(button); if (current_plugin && !strcmp(current_plugin, plugins[i])) current = button; i++; } fep->plugins = plugins; } if (!button) { /* No plugins installed for this mime type */ ac = 0; XtSetArg (av[ac], XmNsensitive, False); ac++; button = XmCreatePushButtonGadget(fep->plugin_pulldown, "plugin0", av, ac); fe_SetString(button, XmNlabelString, XP_GetString(XFE_NO_PLUGINS)); XtManageChild(button); XtVaSetValues(fep->plugin_option, XmNsensitive, False, 0); XtVaSetValues(fep->plugin_b, XmNsensitive, False, 0); current = button; } else { XtVaSetValues(fep->plugin_b, XmNsensitive, True, 0); if (!current) current = button; } XtVaSetValues(fep->plugin_option, XmNmenuHistory, current, 0); } static void fe_helpers_build_exts(char *ext, NET_cdataStruct *cd) { int n = cd->num_exts; cd->exts = (char **) (n ? XP_REALLOC(cd->exts, (n+1)*sizeof(char *)) : XP_ALLOC(sizeof(char *))); if(!cd->exts) return; cd->exts[n] = 0; StrAllocCopy(cd->exts[n], ext); cd->num_exts = ++n; } static char * fe_helpers_construct_new_mailcap_string(NET_mdataStruct *md, char* contenttype, char *command, char *flag) { char *str = NULL; char *buf0 = 0; char buf1[1024]; char buf2[1024]; int len; memset(buf1, '\0', 1024); memset(buf2, '\0', 1024); if ( !md && !contenttype ) return str; else if ( command && *command && flag && *flag ) { sprintf(buf1, "%s\n%s;%s", FE_MOZILLA_MAILCAP_COMMENT, md? md->contenttype: contenttype ,command ); sprintf(buf2, ";\\\n\t%s=%s", NET_MOZILLA_FLAGS, flag); len = strlen(buf1)+strlen(buf2)+1; buf0 = (char*)malloc(len*sizeof(char)); memset(buf0, '\0', len); strcpy(buf0, buf1); strcat(buf0, buf2); } else if ( command && *command ) { /* APPLICATION MODE */ sprintf(buf1, "%s\n%s;%s", FE_MOZILLA_MAILCAP_COMMENT, md ? md->contenttype: contenttype , command); len = strlen(buf1)+1; buf0 = (char*)malloc(len*sizeof(char)); memset(buf0, '\0', len); strcpy(buf0, buf1); } else if ( flag && *flag ) { sprintf(buf1, "%s\n%s;", FE_MOZILLA_MAILCAP_COMMENT, md? md->contenttype: contenttype ); sprintf(buf2, ";\\\n\t%s=%s", NET_MOZILLA_FLAGS, flag); len = strlen(buf1)+strlen(buf2)+1; buf0 = (char*)malloc(len*sizeof(char)); memset(buf0, '\0', len); strcpy(buf0, buf1); strcat(buf0, buf2); } else { sprintf(buf1, "%s\n%s;", FE_MOZILLA_MAILCAP_COMMENT, md? md->contenttype: contenttype ); sprintf(buf2, ";\\\n\t%s=%s", NET_MOZILLA_FLAGS, NET_COMMAND_UNKNOWN); len = strlen(buf1)+strlen(buf2)+1; buf0 = (char*)malloc(len*sizeof(char)); memset(buf0, '\0', len); strcpy(buf0, buf1); strcat(buf0, buf2); } memset(buf1, '\0', strlen(buf1)); memset(buf2, '\0', strlen(buf2)); if (md && md->label && *md->label) sprintf(buf1, ";\\\n\t%s=%s", "description", md->label ); if ( md && md->testcommand && *md->testcommand) sprintf(buf2, ";\\\n\t%s=%s", "test", md->testcommand ); len = strlen(buf0)+strlen(buf1)+strlen(buf2)+strlen("\n")+1; str = (char*)malloc(len*sizeof(char)); memset(str, '\0', len); strcpy(str, buf0); strcat(str, buf1); strcat(str, buf2); free(buf0); buf0 = 0; return str; } void fe_helpers_update_mailcap_entry (char *mimeType, NET_mdataStruct *md, char *flag ) { char *oldStr = NULL; char *src_str = 0; if (md) { oldStr = md->src_string; md->src_string = 0; } if ( !oldStr || !strlen(oldStr) ) src_str = fe_helpers_construct_new_mailcap_string (md, mimeType, md? md->command: NULL,flag); else { src_str = fe_helpers_updateKey(oldStr, NET_MOZILLA_FLAGS, flag, True); if ( !src_str ) src_str = fe_helpers_appendKey(oldStr, NET_MOZILLA_FLAGS, flag, 1); XP_FREE(oldStr); } if ( md ) { if ( md->src_string ) XP_FREE(md->src_string); if ( src_str && *src_str) md->src_string = src_str; if ( md->xmode ) XP_FREE(md->xmode); md->xmode = strdup(flag); md->is_modified = 1; } else { fe_helpers_add_new_mailcap_data(mimeType, src_str, NULL, flag, 1); XP_FREE(src_str); } } static void fe_helpers_build_handle(struct fe_prefs_helpers_data *fep) { NET_mdataStruct *old_md = NULL; char *src_str; char *oldStr = NULL; old_md = fe_helpers_get_mailcap_from_type(fep->cd->ci.type); /* old_md might be marked "Deleted", but that's okay */ /* because we will replace it with the new md data value */ if ( XmToggleButtonGetState(fep->navigator_b) ) { fe_helpers_update_mailcap_entry(fep->cd->ci.type, old_md, NET_COMMAND_NETSCAPE); } else if (XmToggleButtonGetState(fep->plugin_b)) { Widget w; char *value; int n = 0; XtVaGetValues(fep->plugin_option, XmNmenuHistory, &w, 0); XtVaGetValues(w, XmNuserData, &n, 0); value = PR_smprintf("%s%s", NET_COMMAND_PLUGIN, fep->plugins[n]); fe_helpers_update_mailcap_entry(fep->cd->ci.type, old_md, value); XP_FREE(value); } else if (XmToggleButtonGetState(fep->app_b)) { char * text = fe_GetTextField(fep->app_text); if ( text && *text) { text = fe_StringTrim(text); if( old_md ) { oldStr = old_md->src_string; old_md->src_string = 0; } if ( !oldStr || !strlen(oldStr) ) src_str = fe_helpers_construct_new_mailcap_string (old_md, fep->cd->ci.type, text, NULL); else { src_str = fe_helpers_addCommand (oldStr, text); XP_FREE(oldStr); oldStr = src_str; src_str = fe_helpers_deleteKey(oldStr, NET_MOZILLA_FLAGS, 1); if ( src_str ) XP_FREE(oldStr); else src_str = oldStr; } if ( old_md ) { StrAllocCopy(old_md->command, text); if ( old_md->src_string ) XP_FREE(old_md->src_string); old_md->src_string = 0; if ( src_str && *src_str ) old_md->src_string = src_str; if (old_md->xmode) XP_FREE(old_md->xmode); old_md->xmode = 0; old_md->is_modified = 1; } else { fe_helpers_add_new_mailcap_data(fep->cd->ci.type, src_str,text, NULL, 1); XP_FREE(src_str); } } else { if ( old_md ) { oldStr = old_md->src_string; old_md->src_string = 0; } if ( !oldStr || !strlen(oldStr) ) { src_str = fe_helpers_construct_new_mailcap_string (old_md, fep->cd->ci.type, NULL, NET_COMMAND_UNKNOWN); } else { src_str = fe_helpers_deleteCommand(oldStr); XP_FREE(oldStr); oldStr = src_str; src_str = fe_helpers_updateKey(oldStr, NET_MOZILLA_FLAGS, NET_COMMAND_UNKNOWN, True); if ( !src_str ) src_str = fe_helpers_appendKey ( oldStr, NET_MOZILLA_FLAGS, NET_COMMAND_UNKNOWN, 1); XP_FREE(oldStr); } if ( old_md ) { StrAllocCopy(old_md->command, text); if ( old_md->src_string ) XP_FREE(old_md->src_string); old_md->src_string = 0; if ( src_str && *src_str ) old_md->src_string = src_str; if (old_md->xmode) XP_FREE(old_md->xmode); old_md->xmode = strdup(NET_COMMAND_UNKNOWN); old_md->is_modified = 1; } else { fe_helpers_add_new_mailcap_data(fep->cd->ci.type, src_str,NULL, NET_COMMAND_UNKNOWN, 1); XP_FREE(src_str); } } if (text) XP_FREE(text); } else if (XmToggleButtonGetState(fep->save_b)) { fe_helpers_update_mailcap_entry(fep->cd->ci.type, old_md, NET_COMMAND_SAVE_TO_DISK); } else /* Everything else, we set it to be unknown */ { fe_helpers_update_mailcap_entry(fep->cd->ci.type, old_md, NET_COMMAND_UNKNOWN); } } static Boolean fe_helpers_get_mime_data_real_pos(NET_cdataStruct *old_cd, int *real_pos) { Boolean found = False; XP_List *infoList = cinfo_MasterListPointer(); NET_cdataStruct *cd; if (!infoList) return found; *real_pos = 0; while ((cd=(NET_cdataStruct*)XP_ListNextObject(infoList))) { if ( !fe_helpers_is_deleted_type(cd) ) { if ( cd->ci.type ) /* should skip the encoding ones which type = null */ { if ( old_cd == cd ) { found = True; break; } else (*real_pos)++; } } } return found; } static NET_cdataStruct * fe_helpers_get_exist_data(NET_cdataStruct *old_cd, int *old_pos) { NET_cdataStruct *found_cd = NULL; NET_cdataStruct *cd = NULL; XP_List *infoList = cinfo_MasterListPointer(); *old_pos = 0; if ( !infoList ) return found_cd; while ((cd= (NET_cdataStruct *)XP_ListNextObject(infoList))) { if ( old_cd->ci.type && cd->ci.type ) { if( !strcasecomp(old_cd->ci.type, cd->ci.type)) { /* found matching type regardless whether it is deleted one or not */ /* caller needs to decide what they want to do with this old_cd */ found_cd = cd; break; } else (*old_pos)++; } } return found_cd; } static NET_cdataStruct * fe_helpers_can_combine ( NET_cdataStruct *new_cd, int* old_pos) { NET_cdataStruct *old_cd = NULL; old_cd = fe_helpers_get_exist_data(new_cd, old_pos); return old_cd; } static Boolean fe_helpers_start_new_line( char *old_string, char *de, int n ) { Boolean yes = False; int i = 1; char *str = 0; char *string = strdup(old_string); while (1) { while ((*string) && XP_IS_SPACE(*string)) ++string; if ( *string && (*string != '#') ) { if ( string && de && n > 0) { str = XP_STRTOK( string, de); while ( i < n || str ) { str = XP_STRTOK(NULL, de); i++; } if ( i >= n ) /* String ended */ { yes = True; break; } } } else { while ((*string) && (*string != '\n')) ++string; if (*string && *string == '\n') string++; else break; } } return yes; } static char * fe_helpers_new_string(char *old_str, char* type, char *value, char *del) { char *str = 0 ; int len = 0; Boolean newline = False; Boolean quoted = False; if ( !value || !*value) { if ( old_str ) { str = (char*)malloc((strlen(old_str)+1)*sizeof(char)); strcpy(str, old_str); return str; } else return NULL; } if (!old_str) { if ( !strcmp(type, DESC) || !strcmp(type, EXTS) ) { len = strlen(type) + strlen("=") + strlen(value) + 2 * strlen("\"") + strlen(del) + 1; str = (char*)malloc(len *sizeof(char)); memset(str, '\0', len); strcpy(str, type); strcat(str, "="); strcat(str, "\""); strcat(str, value); strcat(str, "\""); strcat(str, del); } else { len = strlen(type) +strlen("=") + strlen(value) + strlen(del) +1; str = (char*)malloc(len *sizeof(char)); memset(str, '\0', len); strcpy(str, type); strcat(str, "="); strcat(str, value); strcat(str, del); } } else { if ( old_str[strlen(old_str)-1] == '\n') old_str[strlen(old_str)-1] = '\0'; if (fe_helpers_start_new_line(old_str, del, 2) ) { newline = True; len = strlen(" \\\n"); } if ( !strcmp(type, DESC) || !strcmp(type, EXTS) ) { quoted = True; len = len + 2 * strlen("\"") ; } len = len + strlen(old_str)+ strlen("\t\t")+ strlen(type) + strlen("=") + strlen(value)+ strlen(del) + 1; str = (char*)malloc(len*sizeof(char)); memset(str, '\0', len); strcpy(str, old_str); if ( newline ) strcat(str, " \\\n"); else strcat(str, "\t\t"); strcat(str, type); strcat(str, "="); if (quoted) strcat(str, "\""); strcat(str, value); if (quoted) strcat(str, "\""); strcat(str, del); } return str; } static char * fe_replace_new_mime_string(NET_cdataStruct *old_cd, NET_cdataStruct *new_cd) { int n; char old_exts[200]; char new_exts[200]; char *str = NULL; char *old_str = NULL; if ( !old_cd->src_string ) return NULL; str = strdup(old_cd->src_string); memset(old_exts, '\0', 200); memset(new_exts, '\0', 200); if (old_cd->ci.type && *old_cd->ci.type ) { if (new_cd->ci.type && *new_cd->ci.type ) { old_str = str; str = fe_helpers_updateKey(old_str, TYPE, new_cd->ci.type, 0 ); if ( !str ) { str = fe_helpers_new_string(old_str, TYPE, new_cd->ci.type, SPACE); } XP_FREE(old_str); } else { old_str = str; str = fe_helpers_deleteKey(str, TYPE, 0 ); XP_FREE(old_str); } } else { old_str = str; str = fe_helpers_new_string(str, TYPE, new_cd->ci.type, SPACE); XP_FREE(old_str); } if (old_cd->ci.desc && *old_cd->ci.desc ) { if (new_cd->ci.desc && *new_cd->ci.desc ) { old_str = str; str = fe_helpers_updateKey(str, DESC, new_cd->ci.desc, 0 ); if ( !str ) { str = fe_helpers_new_string(old_str, DESC, new_cd->ci.desc, SPACE); } XP_FREE(old_str); } else { old_str = str; str = fe_helpers_deleteKey(str, DESC,0 ); XP_FREE(old_str); } } else { old_str = str; str = fe_helpers_new_string(str, DESC, new_cd->ci.desc, SPACE); XP_FREE(old_str); } if ( old_cd->exts && *old_cd->exts ) { for (n= 0; n < old_cd->num_exts; n++ ) { if ( n > 0 ) strcat( old_exts, ","); if ( n == 0 ) strcpy(old_exts, old_cd->exts[n]); else strcat(old_exts, old_cd->exts[n]); } if ( new_cd->num_exts > 0 ) { for (n= 0; n < new_cd->num_exts; n++ ) { if ( n > 0 ) strcat( new_exts, ","); if ( n == 0 ) strcpy(new_exts, new_cd->exts[n]); else strcat(new_exts, new_cd->exts[n]); } old_str = str; str = fe_helpers_updateKey(str, EXTS, new_exts, 0 ); if ( !str ) { str = fe_helpers_new_string(old_str, EXTS, new_exts, SPACE); } XP_FREE(old_str); } else { old_str = str; str = fe_helpers_deleteKey(str, EXTS, 0); XP_FREE(old_str); } } else { if ( new_cd->num_exts > 0 ) { for (n= 0; n < new_cd->num_exts; n++ ) { if ( n > 0 ) strcat( new_exts, ","); strcat(new_exts, new_cd->exts[n]); } old_str = str; str = fe_helpers_new_string(str, EXTS, new_exts, SPACE); XP_FREE(old_str); } } return str; } static char * fe_helpers_construct_new_mime_string(NET_cdataStruct *new_cd) { int n; int len; char buffer1[1024]; char buffer2[1024]; char *string = 0; char *str = 0; char *old_str = NULL; XP_List *masterList = cinfo_MasterListPointer(); strcpy(buffer1, FE_MOZILLA_MIME_COMMENT); if ( NET_IsOldMimeTypes(masterList) ) { sprintf(buffer2, "%s", new_cd->ci.type); if ( new_cd->num_exts > 0 ) for ( n = 0; n < new_cd->num_exts; n++ ) { if (n == 0 ) strcat(buffer2, SPACE); else strcat(buffer2, SPACE); strcat(buffer2, new_cd->exts[n]); } len = strlen(buffer1)+strlen(buffer2)+ 2*strlen("\n")+1; string = (char*)malloc(len *sizeof(char)); strcpy(string, buffer1); strcat(string, "\n"); strcat(string, buffer2); } else { n = 0; if ( new_cd->ci.type && *new_cd->ci.type ) { str = fe_helpers_new_string(old_str, TYPE, new_cd->ci.type, SPACE); XP_FREE(old_str); } if ( new_cd->ci.encoding && *new_cd->ci.encoding ) { old_str = str; str = fe_helpers_new_string(old_str, ENC, new_cd->ci.encoding, SPACE); XP_FREE(old_str); } if ( new_cd->ci.language && *new_cd->ci.language) { old_str = str; str = fe_helpers_new_string(old_str, LANG, new_cd->ci.language, SPACE); XP_FREE(old_str); } if ( new_cd->ci.desc && *new_cd->ci.desc) { old_str = str; str = fe_helpers_new_string(old_str, DESC, new_cd->ci.desc, SPACE); XP_FREE(old_str); } if ( new_cd->ci.alt_text && *new_cd->ci.alt_text) { old_str = str; str = fe_helpers_new_string(old_str, ALT, new_cd->ci.alt_text, SPACE); XP_FREE(old_str); } if ( new_cd->ci.icon && *new_cd->ci.icon) { old_str = str; str = fe_helpers_new_string(old_str, ICON, new_cd->ci.icon, SPACE); XP_FREE(old_str); } if ( new_cd->exts && *new_cd->exts) { char exts[1024]; memset(exts, '\0', 1024); for (n= 0; n < new_cd->num_exts; n++ ) { if ( n > 0 ) strcat( exts, ","); strcat(exts, new_cd->exts[n]); } old_str = str; str = fe_helpers_new_string(old_str, EXTS, exts, SPACE); XP_FREE(old_str); } len = strlen(buffer1)+strlen(str)+ 2 *strlen("\n") + 1; string = (char*)malloc(len *sizeof(char)); memset(string, '\0', len); strcpy(string, buffer1); strcat(string, "\n"); strcat(string, str); } return string; } static void fe_helpers_done_cb(Widget widget, XtPointer closure, XtPointer call_data) { struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure; char *text = 0; char *u = 0; int i; int old_pos; NET_cdataStruct *old_cd = NULL; NET_cdataStruct *new_cd = NULL; NET_mdataStruct *md = NULL; Boolean add_new_cd = False; char *src_string =0; int real_pos; fe_MarkHelpersModified(fep->context); /* Type is critical. If this field is empty, then basically we don't do a thing here */ text = fe_GetTextField(fep->mime_types_text); if ( !text ) return; text = fe_StringTrim(text); if ( !strlen(text)) { FE_Alert(fep->context, XP_GetString(XFE_HELPERS_EMPTY_MIMETYPE)); XP_FREE(text); return; } if(text) XP_FREE(text); /* Empty type Business has been taken care of */ /* Do some serious stuff here now...*/ new_cd = NET_cdataCreate(); new_cd->is_local = True; if ( fep->cd ) { new_cd->is_external = fep->cd->is_external; new_cd->is_modified = 1; } else{ new_cd->is_external = 1; new_cd->is_modified = 1; /* If new entry was deleted before commit, we don't want to save the info out*/ new_cd->is_new = 1; /* remember this for deletion*/ add_new_cd = True; } /* Description */ text = fe_GetTextField(fep->mime_types_desc_text); if ( text && *text ) { fe_StringTrim(text); StrAllocCopy(new_cd->ci.desc, text); } if(text) XP_FREE(text); /* Type */ text = fe_GetTextField(fep->mime_types_text); if ( text && *text ){ fe_StringTrim(text); StrAllocCopy( new_cd->ci.type, text); } if(text) XP_FREE(text); /* Suffix */ text = fe_GetTextField(fep->mime_types_suffix_text); u = XP_STRTOK(text, ","); while (u) { u = fe_StringTrim(u); fe_helpers_build_exts(u, new_cd); u = XP_STRTOK(NULL, ","); } if(text) XP_FREE(text); if ( (old_cd=fe_helpers_can_combine (new_cd, &old_pos)) ) { if ( !fe_helpers_is_deleted_type(old_cd) ) { /* Only cd's that aren't deleted are displayed in the list */ /* Therefore, we need to make sure if the item is in the list */ /* in order to delete */ if ( fe_helpers_get_mime_data_real_pos(old_cd, &real_pos) ) old_pos = real_pos; if ( old_pos > fep->pos ) XmLGridDeleteRows(fep->helpers_list, XmCONTENT, old_pos, 1); else if (fep->pos > old_pos ) { XmLGridDeleteRows(fep->helpers_list, XmCONTENT, old_pos, 1); fep->pos -= 1; } else if ( fep->pos == 0 && old_pos == 0) { XmLGridDeleteRows(fep->helpers_list, XmCONTENT, old_pos, 1); } } /* CanCombine=True will remove the fep->cd from the list */ /* Therefore, make the new one the current */ /* If action = add_new_cd, and can_combine = true, we should remove the old one */ if ( add_new_cd ) { NET_cdataRemove(old_cd); old_cd = NULL; } } if ( fep->cd ) /* Then, this is not an action: NEW */ { if ( !fep->cd->is_local && !fep->cd->is_external ) { /* read from Global mime.type in old mime format */ /* convert it to the new format here */ src_string = fe_helpers_construct_new_mime_string( new_cd ); } else if ( !fep->cd->is_local && !fep->cd->num_exts ) { /* This entry is added by an existing mailcap type */ src_string = fe_helpers_construct_new_mime_string(new_cd); } else src_string = fe_replace_new_mime_string( fep->cd, new_cd ); XP_FREE(fep->cd->src_string); fep->cd->src_string = src_string; XP_FREE(fep->cd->ci.desc ); XP_FREE(fep->cd->ci.type ); fep->cd->ci.desc = 0; fep->cd->ci.type = 0; for ( i = 0; i < fep->cd->num_exts; i++ ) XP_FREE (fep->cd->exts[i]); XP_FREE(fep->cd->exts); fep->cd->exts = 0; fep->cd->num_exts = 0; fep->cd->is_external = new_cd->is_external; fep->cd->is_modified = new_cd->is_modified; StrAllocCopy(fep->cd->ci.desc, new_cd->ci.desc); StrAllocCopy(fep->cd->ci.type, new_cd->ci.type); for ( i = 0; i < new_cd->num_exts; i++ ) fe_helpers_build_exts(new_cd->exts[i], fep->cd); NET_cdataFree(new_cd); } else { src_string = fe_helpers_construct_new_mime_string( new_cd ); if ( new_cd->src_string) XP_FREE(new_cd->src_string); new_cd->src_string = src_string; fep->cd = new_cd; } fe_helpers_build_handle(fep); if ( add_new_cd && (fep->pos == 0)) { fep->pos = -1; NET_cdataAdd(fep->cd); } if ( !fe_helpers_is_deleted_type(fep->cd) ) { md = fe_helpers_get_mailcap_from_type(fep->cd->ci.type); fe_helpers_append_type_to_list(fep, fep->cd, md, fep->pos); } XtDestroyWidget(widget); } static void fe_helpers_cancel_cb(Widget widget, XtPointer closure, XtPointer call_data) { XtDestroyWidget(widget); } static void fe_helpers_destroy_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure; int i; if (!fep->editor) /* The helper edit dialog is not up. Do nothing. */ return; fep->editor = NULL; fep->pos = 0; fep->cd = NULL; /* Free the backend allocated plugin names */ for (i=0; fep->plugins && fep->plugins[i]; i++) XP_FREE(fep->plugins[i]); if (fep->plugins) XP_FREE(fep->plugins); fep->plugins = 0; } static void fe_helpers_verify_toggle_cb( Widget widget, XtPointer closure, XtPointer call_data) { struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure; XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)call_data; if (!cb->set) { XtVaSetValues (widget, XmNset, True, 0); } else if (widget == fep->navigator_b) { XtVaSetValues (fep->plugin_b, XmNset, False, 0); XtVaSetValues (fep->app_b, XmNset, False, 0); XtVaSetValues (fep->save_b, XmNset, False, 0); XtVaSetValues (fep->app_text, XmNsensitive, False, 0); XtVaSetValues (fep->unknown_b, XmNset, False, 0); } else if (widget == fep->plugin_b) { Widget w; int n; char *pluginName; XtVaGetValues(fep->plugin_option, XmNmenuHistory, &w, 0); XtVaGetValues(w, XmNuserData, &n, 0); pluginName = fep->plugins[n]; fe_helpers_plugin_selected(fep, pluginName); XtVaSetValues (fep->navigator_b, XmNset, False, 0); XtVaSetValues (fep->app_b, XmNset, False, 0); XtVaSetValues (fep->save_b, XmNset, False, 0); XtVaSetValues (fep->app_text, XmNsensitive, False, 0); XtVaSetValues (fep->unknown_b, XmNset, False, 0); } else if (widget == fep->app_b) { XtVaSetValues (fep->navigator_b, XmNset, False, 0); XtVaSetValues (fep->plugin_b, XmNset, False, 0); XtVaSetValues (fep->save_b, XmNset, False, 0); XtVaSetValues (fep->app_text, XmNsensitive, True, 0); XtVaSetValues (fep->unknown_b, XmNset, False, 0); } else if (widget == fep->save_b) { XtVaSetValues (fep->navigator_b, XmNset, False, 0); XtVaSetValues (fep->plugin_b, XmNset, False, 0); XtVaSetValues (fep->app_b, XmNset, False, 0); XtVaSetValues (fep->app_text, XmNsensitive, False, 0); XtVaSetValues (fep->unknown_b, XmNset, False, 0); } else if (widget == fep->unknown_b) { XtVaSetValues (fep->navigator_b, XmNset, False, 0); XtVaSetValues (fep->plugin_b, XmNset, False, 0); XtVaSetValues (fep->app_b, XmNset, False, 0); XtVaSetValues (fep->app_text, XmNsensitive, False, 0); XtVaSetValues (fep->save_b, XmNset, False, 0); } else abort (); } static Widget fe_helpers_make_edit_dialog(struct fe_prefs_helpers_data *fep) { Widget mainw = CONTEXT_WIDGET (fep->context); Widget dialog; Widget frame1; Widget form, form1, form2; Widget mime_types_desc_label, mime_types_desc_text; Widget mime_types_label, mime_types_text; Widget mime_types_suffix_label, mime_types_suffix_text; Widget navigator_b, plugin_b, app_b, app_text, app_browse; Widget save_b, unknown_b; Widget label1; Widget kids[30]; Widget plugin_option; Widget plugin_pulldown; Dimension size, space; Visual *v = 0; Colormap cmap = 0; Cardinal depth = 0; Arg av[20]; int ac; int i; /* If the pref is up, we need to make this the child of the pref dialog */ if (CONTEXT_DATA(fep->context)->currentPrefDialog) mainw = CONTEXT_DATA(fep->context)->currentPrefDialog; while(!XtIsWMShell(mainw) && (XtParent(mainw)!=0)) mainw = XtParent(mainw); XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap, XtNdepth, &depth, 0); ac = 0; XtSetArg (av[ac], XmNvisual, v); ac++; XtSetArg (av[ac], XmNdepth, depth); ac++; XtSetArg (av[ac], XmNcolormap, cmap); ac++; XtSetArg (av[ac], XmNtransientFor, mainw); ac++; XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++; XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); ac++; XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++; XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++; XtSetArg (av[ac], XmNautoUnmanage, False); ac++; /* XtSetArg (av[ac], XmNnoResize, True); ac++; */ dialog = XmCreatePromptDialog (mainw, "helperEditor", av, ac); XtUnmanageChild(XmSelectionBoxGetChild (dialog, XmDIALOG_SEPARATOR)); XtUnmanageChild(XmSelectionBoxGetChild (dialog, XmDIALOG_TEXT)); XtUnmanageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL)); XtUnmanageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_APPLY_BUTTON)); #ifdef NO_HELP XtUnmanageChild(XmSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON)); #endif XtAddCallback (dialog, XmNokCallback, fe_helpers_done_cb, fep); XtAddCallback (dialog, XmNcancelCallback, fe_helpers_cancel_cb, fep); XtAddCallback (dialog, XmNdestroyCallback, fe_helpers_destroy_cb, fep); ac = 0; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; form = XmCreateForm (dialog, "helperEdit", av, ac); XtManageChild (form); ac = 0; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_NONE); ac++; form1 = XmCreateForm (form, "helperEditForm", av, ac); ac = 0; i = 0; kids[i++] = mime_types_desc_label= XmCreateLabelGadget (form1, "mimeTypesDescriptionLabel", av, ac); kids[i++] = mime_types_desc_text = fe_CreateTextField (form1, "mimeTypesDescriptionText",av,ac); kids[i++] = mime_types_label = XmCreateLabelGadget (form1, "mimeTypesLabel", av, ac); kids[i++] = mime_types_text = fe_CreateTextField (form1, "mimeTypesText",av,ac); kids[i++] = mime_types_suffix_label = XmCreateLabelGadget (form1, "mimeTypesSuffixLabel", av, ac); kids[i++] = mime_types_suffix_text = fe_CreateTextField (form1, "mimeTypesSuffixText",av,ac); if (fe_globalData.nonterminal_text_translations) { XtOverrideTranslations (mime_types_desc_text, fe_globalData.nonterminal_text_translations); XtOverrideTranslations (mime_types_text, fe_globalData.nonterminal_text_translations); } XtAddCallback(mime_types_text, XmNvalueChangedCallback, fe_helpers_set_handle_by_cb, fep); /* Layout the helper editor widgets in the form1 */ XtVaSetValues (mime_types_desc_label, XmNalignment, XmALIGNMENT_END, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_NONE, 0); XtVaSetValues (mime_types_desc_text, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, mime_types_desc_label, XmNrightAttachment, XmATTACH_FORM, 0); XtVaSetValues(mime_types_desc_label, XmNheight, XfeHeight(mime_types_desc_text),0); XtVaSetValues (mime_types_label, XmNalignment, XmALIGNMENT_END, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, mime_types_desc_label, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET, XmNrightWidget, mime_types_desc_label, 0); XtVaSetValues (mime_types_text, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget,mime_types_desc_text , XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, mime_types_desc_text, XmNrightAttachment, XmATTACH_FORM, 0); XtVaSetValues(mime_types_label, XmNheight, XfeHeight(mime_types_text), 0); XtVaSetValues (mime_types_suffix_label, XmNalignment, XmALIGNMENT_END, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, mime_types_label, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET, XmNrightWidget, mime_types_label, 0); XtVaSetValues (mime_types_suffix_text, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, mime_types_text, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, mime_types_suffix_label, XmNrightAttachment, XmATTACH_FORM, 0); XtVaSetValues(mime_types_suffix_label, XmNheight, XfeHeight(mime_types_suffix_text), 0); XtManageChildren(kids,i); XtManageChild(form1); ac = 0; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg (av [ac], XmNtopWidget, form1); ac++; XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++; frame1 = XmCreateFrame (form, "helperEditFrame", av, ac); ac = 0; XtSetArg (av [ac], XmNchildType, XmFRAME_TITLE_CHILD); ac++; label1 = XmCreateLabelGadget (frame1, "helperEditFrameLabel", av, ac); ac = 0; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++; form2 = XmCreateForm (frame1, "helperEditHandleBox", av, ac); ac = 0; i = 0; kids [i++] = navigator_b = XmCreateToggleButtonGadget (form2, "helperEditNavigator", av,ac); kids [i++] = plugin_b = XmCreateToggleButtonGadget (form2, "helperEditPlugin", av,ac); ac = 0; XtSetArg (av[ac], XmNvisual, v); ac++; XtSetArg (av[ac], XmNdepth, depth); ac++; XtSetArg (av[ac], XmNcolormap, cmap); ac++; plugin_pulldown = XmCreatePulldownMenu (form2, "pluginPullDown", av, ac); ac = 0; XtSetArg(av[ac], XmNsubMenuId, plugin_pulldown); ac++; kids [i++] = plugin_option = fe_CreateOptionMenu (form2,"pluginMenu", av, ac); kids [i++] = app_b = XmCreateToggleButtonGadget (form2, "helperEditApp", av,ac); kids [i++] = app_text = fe_CreateTextField (form2, "helperEditAppText", av,ac); kids [i++] = app_browse = XmCreatePushButton (form2, "helperEditAppBrowse", av,ac); kids [i++] = save_b = XmCreateToggleButtonGadget (form2, "helperEditSave", av,ac); kids [i++] = unknown_b = XmCreateToggleButtonGadget (form2, "helperEditUnknown", av,ac); fep->mime_types_desc_text = mime_types_desc_text; fep->mime_types_text = mime_types_text; fep->mime_types_suffix_text = mime_types_suffix_text; fep->navigator_b = navigator_b; fep->plugin_b = plugin_b; fep->app_b = app_b; fep->app_text = app_text; fep->app_browse = app_browse; fep->save_b = save_b; fep->unknown_b = unknown_b; fep->plugin_option = plugin_option; fep->plugin_pulldown = plugin_pulldown; fe_helpers_build_plugin_list(fep, (fep->cd ? fep->cd->ci.type:NULL)); XtVaSetValues (navigator_b, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_NONE, XmNsensitive, True, 0); XtVaSetValues (plugin_b, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, plugin_option, XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, XmNbottomWidget, plugin_option, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, navigator_b, XmNrightAttachment, XmATTACH_NONE, 0); XtVaSetValues (plugin_option, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, navigator_b, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, XfeWidth(plugin_b) + 20, XmNrightAttachment, XmATTACH_FORM, 0); XtVaSetValues (app_b, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, plugin_option, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, plugin_b, XmNrightAttachment, XmATTACH_NONE, 0); XtVaGetValues( app_b, XmNindicatorSize, &size, XmNspacing, &space, 0 ); XtVaSetValues (app_text, XmNsensitive, False, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, app_b, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, plugin_b, XmNleftOffset, size+space, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, XfeWidth(app_browse) + 10, 0); XtVaSetValues (app_browse, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopWidget, app_text, XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, XmNbottomWidget, app_text, XmNleftAttachment, XmATTACH_NONE, XmNrightAttachment, XmATTACH_FORM, 0); XtVaSetValues (save_b, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, app_text, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, app_b, XmNrightAttachment, XmATTACH_NONE, 0); XtVaSetValues (unknown_b, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, save_b, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, save_b, XmNrightAttachment, XmATTACH_NONE, 0); XtAddCallback(navigator_b, XmNvalueChangedCallback, fe_helpers_verify_toggle_cb, fep); XtAddCallback(plugin_b, XmNvalueChangedCallback, fe_helpers_verify_toggle_cb, fep); XtAddCallback(app_b, XmNvalueChangedCallback, fe_helpers_verify_toggle_cb, fep); XtAddCallback(save_b, XmNvalueChangedCallback, fe_helpers_verify_toggle_cb, fep); XtAddCallback(unknown_b, XmNvalueChangedCallback, fe_helpers_verify_toggle_cb, fep); XtAddCallback(app_browse, XmNactivateCallback, fe_helpers_application_browse_cb, fep); XtManageChildren (kids, i); XtManageChild(form2); XtManageChild(label1); XtManageChild(frame1); XtManageChild(form); return dialog; } static void fe_helpers_application_browse_cb(Widget widget, XtPointer closure, XtPointer call_data) { struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure; fe_browse_file_of_text (fep->context, fep->app_text, False); } static Bool fe_helpers_handle_by_netscape(char *type) { Bool rightType = False; if (!strcmp(type, TEXT_HTML) || !strcmp(type, TEXT_MDL)|| !strcmp(type, TEXT_PLAIN)|| !strcmp(type, IMAGE_GIF) || !strcmp(type, IMAGE_JPG) || !strcmp(type, IMAGE_PJPG) || !strcmp(type, IMAGE_XBM) || !strcmp(type, IMAGE_XBM2) || !strcmp(type, IMAGE_XBM3) || !strcmp(type, APPLICATION_PRE_ENCRYPTED) || !strcmp(type, APPLICATION_NS_PROXY_AUTOCONFIG) ) { rightType = True; } return rightType; } static Bool fe_helpers_handle_by_saveToDisk(char *type) { Bool rightType = False; if ( !strcmp(type, APPLICATION_OCTET_STREAM) ) rightType = True; return rightType; } static XP_Bool fe_helpers_handle_by_plugin(struct fe_prefs_helpers_data *fep, char *type) { Bool b; /* Create plugins options menu and sensitize the plugin option menu and toggle button, depending on the mimetype passed in */ fe_helpers_build_plugin_list(fep, type); XtVaGetValues(fep->plugin_b, XmNsensitive, &b, 0); return(b); } static void fe_helpers_set_handle_by_flag ( struct fe_prefs_helpers_data *fep, NET_cdataStruct *cd) { NET_mdataStruct *md = NULL; XtVaSetValues(fep->navigator_b, XmNsensitive, False, 0); /* Netscape Type ?*/ if (fe_helpers_handle_by_netscape(cd->ci.type) ) { XtVaSetValues(fep->navigator_b, XmNsensitive, True, 0); } md = fe_helpers_get_mailcap_from_type(cd->ci.type); if ( md && md->command && *md->command ) { XtVaSetValues(fep->app_text, XmNsensitive, False, 0 ); fe_SetTextField(fep->app_text, md->command); } if (md && md->xmode && *md->xmode) { md->xmode = fe_StringTrim(md->xmode); if (!strcmp(md->xmode, NET_COMMAND_UNKNOWN)) XtVaSetValues(fep->unknown_b, XmNset, True, 0 ); else if (fe_IsMailcapEntryPlugin(md)) XtVaSetValues(fep->plugin_b, XmNset, True, 0 ); else if (!strcmp(md->xmode, NET_COMMAND_SAVE_TO_DISK) || (!strcmp(md->xmode, NET_COMMAND_SAVE_BY_NETSCAPE))) XtVaSetValues(fep->save_b, XmNset, True, 0 ); else if (!strcmp(md->xmode,NET_COMMAND_NETSCAPE)) XtVaSetValues(fep->navigator_b, XmNset, True, 0 ); else if (!strcmp(md->xmode,NET_COMMAND_DELETED)) XtVaSetValues(fep->unknown_b, XmNset, True, 0 ); } else if ( md && md->command && *md->command) { XtVaSetValues(fep->app_b, XmNset, True, 0 ); XtVaSetValues(fep->app_text, XmNsensitive, True, 0 ); } else if (fe_helpers_handle_by_netscape(cd->ci.type) ) XtVaSetValues(fep->navigator_b, XmNset, True, 0 ); else if (fe_helpers_handle_by_saveToDisk(cd->ci.type) ) XtVaSetValues(fep->save_b, XmNset, True, 0 ); else XtVaSetValues(fep->unknown_b, XmNset, True, 0); } static void fe_helpers_set_handle_by_cb (Widget w, XtPointer closure, XtPointer call_data ) { struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure; char *text = NULL; Bool nav_p = False, plugin_p = False; text = fe_GetTextField(fep->mime_types_text); if (text && *text && fe_helpers_handle_by_netscape(text)) { XtVaSetValues(fep->navigator_b, XmNsensitive, True, 0); nav_p = True; } else XtVaSetValues(fep->navigator_b, XmNsensitive, False, 0); if (text && *text && fe_helpers_handle_by_plugin(fep, text)) /* fe_helpers_handle_by_plugin() will sensitize the plugin button. */ plugin_p = True; /* if Navigator used to handle this but cannot anymore, unknown takes over */ if (XmToggleButtonGetState(fep->navigator_b) && !nav_p) XmToggleButtonSetState(fep->unknown_b, True, True); /* if Plugin used to handle this but cannot anymore, unknown takes over */ if (XmToggleButtonGetState(fep->plugin_b) && !plugin_p) XmToggleButtonSetState(fep->unknown_b, True, True); if (text) XP_FREE(text); } static void fe_helpers_fill_edit_with_data(struct fe_prefs_helpers_data *fep, NET_cdataStruct *cd) { int i; char *extensions = 0; /* has to initialize bf. passing to StrAllocCopy() */ if ( !fep || !cd->ci.type || !*cd->ci.type ) return; /* Found Type */ XtVaSetValues(fep->mime_types_text, XmNcursorPosition, 0, 0); fe_SetTextField(fep->mime_types_text, cd->ci.type); /* MIME Description */ if ( cd->ci.desc && *cd->ci.desc ) { XtVaSetValues(fep->mime_types_desc_text, XmNcursorPosition, 0, 0 ); fe_SetTextField(fep->mime_types_desc_text, cd->ci.desc); } /* MIME Suffix */ for ( i = 0; i < cd->num_exts; i++ ) { if ( i == 0 ) { StrAllocCopy(extensions, cd->exts[i] ); } else { extensions = XP_AppendStr(extensions, ","); extensions = XP_AppendStr(extensions, cd->exts[i]); } } if (cd->num_exts > 0 ) { XtVaSetValues(fep->mime_types_suffix_text, XmNcursorPosition, 0, 0 ); XtVaSetValues(fep->mime_types_suffix_text, extensions); } /* Handle By...this mail cap */ fe_helpers_set_handle_by_flag(fep, cd); } static NET_cdataStruct * fe_helpers_get_mime_data_at_pos(int pos) /* Starting from 0 */ { int count = 0; NET_cdataStruct *cd = NULL; XP_List *infoList = cinfo_MasterListPointer(); while((cd = XP_ListNextObject(infoList))) { if ( cd->ci.type && *cd->ci.type && !fe_helpers_is_deleted_type(cd)) { if ( pos == count ) { break; } else count++; } } return cd; } static void fe_helpers_edit_cb( Widget w, XtPointer closure, XtPointer call_data) { NET_cdataStruct *cd = NULL; struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure; int selectedCount; int pos[1]; /* we are browse select, so only 1 row is selected */ selectedCount = XmLGridGetSelectedRowCount(fep->helpers_list); if ( selectedCount != 1 ) return; XmLGridGetSelectedRows(fep->helpers_list, pos, selectedCount); /* pos in the list always start from 0 */ cd = fe_helpers_get_mime_data_at_pos(pos[0]); if ( fep ) { fep->pos = pos[0]; fep->cd = cd; fep->editor = fe_helpers_make_edit_dialog(fep); fe_helpers_fill_edit_with_data(fep, cd); XtManageChild(fep->editor); } } static void fe_helpers_new_cb( Widget w, XtPointer closure, XtPointer call_data) { struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure; if ( fep) { fep->pos = 0; fep->editor = fe_helpers_make_edit_dialog(fep); fep->cd = NULL; XtManageChild(fep->editor); } } static void fe_helpers_delete_cb( Widget w, XtPointer closure, XtPointer call_data) { char *old_str = 0; char *src_str = 0; NET_cdataStruct* cd = NULL; NET_mdataStruct* old_md= NULL; struct fe_prefs_helpers_data *fep = (struct fe_prefs_helpers_data *) closure; int selectedCount; int pos[1]; /* we are browse select, so only 1 row is selected */ selectedCount = XmLGridGetSelectedRowCount(fep->helpers_list); if ( selectedCount != 1 ) return; XmLGridGetSelectedRows(fep->helpers_list, pos, selectedCount); /* pos in the list always start from 0 */ cd = fe_helpers_get_mime_data_at_pos(pos[0]); if ( fep ) { fep->pos = pos[0]; fep->cd = cd; if (XFE_Confirm (fep->context, fe_globalData.helper_app_delete_message)) { fe_MarkHelpersModified(fep->context); old_md = fe_helpers_get_mailcap_from_type(fep->cd->ci.type); if ( old_md ) { /* If there is a mailcap entry, then update to reflect delete */ old_str = old_md->src_string; old_md->src_string = 0; } if ( !old_str || !strlen(old_str)) { src_str = fe_helpers_construct_new_mailcap_string(old_md, fep->cd->ci.type, NULL, NET_COMMAND_DELETED); } else { src_str = fe_helpers_deleteCommand(old_str); XP_FREE(old_str); old_str = src_str; src_str = fe_helpers_updateKey(src_str, NET_MOZILLA_FLAGS, NET_COMMAND_DELETED, 1 ); XP_FREE(old_str); } if ( old_md ) { if (old_md->src_string ) XP_FREE(old_md->src_string); old_md->src_string = 0; if ( src_str && *src_str ) old_md->src_string = src_str; if (old_md->xmode) XP_FREE(old_md->xmode); old_md->xmode = strdup(NET_COMMAND_DELETED); old_md->is_modified = 1; } else { fe_helpers_add_new_mailcap_data(fep->cd->ci.type, src_str, NULL, NET_COMMAND_DELETED, 1); XP_FREE(src_str); } XmLGridDeleteRows(fep->helpers_list, XmCONTENT, fep->pos, 1); if (fep->cd->is_new ) { NET_cdataRemove(fep->cd); if ( old_md ) NET_mdataRemove(old_md); } fep->cd = 0; fep->pos = 0; } } } static void fe_helpers_add_list_row(struct fe_prefs_helpers_data *fep, char *data) { int total ; XtVaGetValues( fep->helpers_list, XmNrows, &total, 0 ); XmLGridAddRows(fep->helpers_list, XmCONTENT, -1, 1); if ( total > 0 ) XmLGridMoveRows(fep->helpers_list, 1, 0, total); XmLGridSetStringsPos(fep->helpers_list, XmCONTENT, 0, XmCONTENT, 0, data); } static void fe_helpers_append_list_row(struct fe_prefs_helpers_data *fep, int row, char *data) { int total ; XtVaGetValues( fep->helpers_list, XmNrows, &total, 0 ); if ( row >= total ) XmLGridAddRows(fep->helpers_list, XmCONTENT, -1, 1); XmLGridSetStringsPos(fep->helpers_list, XmCONTENT, row, XmCONTENT, 0, data); } NET_mdataStruct * fe_helpers_get_mailcap_from_type(char *type) { NET_mdataStruct *md_item= NULL, *new_item = NULL; /* Get beginning of the list */ XP_List *infolist = mailcap_MasterListPointer(); while ((md_item = (NET_mdataStruct *)XP_ListNextObject(infolist))) { if ( type && md_item->contenttype && !XP_STRCASECMP(type, md_item->contenttype)) { new_item = md_item; break; } } return new_item; } static void fe_helpers_append_type_to_list(struct fe_prefs_helpers_data *fep, NET_cdataStruct *cd_item, NET_mdataStruct *md, int pos) { char *desc = 0, *action = 0, *line = 0; if ( cd_item->ci.type && strlen(cd_item->ci.type) ) { cd_item->ci.type = fe_StringTrim(cd_item->ci.type); StrAllocCopy( desc, cd_item->ci.type); } if ( md && md->xmode && *md->xmode ) { if ( !XP_STRCASECMP(md->xmode, NET_COMMAND_NETSCAPE )) StrAllocCopy(action, XP_GetString(XFE_HELPERS_NETSCAPE)); else if (!strcmp(md->xmode, NET_COMMAND_SAVE_TO_DISK) || (!strcmp(md->xmode, NET_COMMAND_SAVE_BY_NETSCAPE))) StrAllocCopy(action, XP_GetString(XFE_HELPERS_SAVE)); else if ( !XP_STRCASECMP(md->xmode, NET_COMMAND_UNKNOWN )) StrAllocCopy(action, XP_GetString(XFE_HELPERS_UNKNOWN)); else if (fe_IsMailcapEntryPlugin(md)) { char *pluginName = fe_GetPluginNameFromMailcapEntry(md); action = PR_smprintf(XP_GetString(XFE_HELPERS_PLUGIN), pluginName); } } else if (md && md->command && *md->command) { md->command = fe_StringTrim(md->command); StrAllocCopy( action, md->command); } else if (fe_helpers_handle_by_netscape(cd_item->ci.type) ) StrAllocCopy(action, XP_GetString(XFE_HELPERS_NETSCAPE)); else if (fe_helpers_handle_by_saveToDisk(cd_item->ci.type)) StrAllocCopy(action, XP_GetString(XFE_HELPERS_SAVE)); else StrAllocCopy(action, XP_GetString(XFE_HELPERS_UNKNOWN)); if ( desc && action ) { line = PR_smprintf("%s|%s", desc, action); if (pos <= 0) fe_helpers_add_list_row(fep, line); else fe_helpers_append_list_row(fep, pos, line); } if (desc) XP_FREE(desc); if (action) XP_FREE(action); if (line) XP_FREE(line); } void fe_helpers_build_mime_list(struct fe_prefs_helpers_data *fep) { int item_count = 0; NET_mdataStruct *md; NET_cdataStruct *cd_item; /* Get beginning of the list */ XP_List *infolist = cinfo_MasterListPointer(); XtVaSetValues( fep->helpers_list, XmNlayoutFrozen, True, NULL); /* Get the file format from the object in order to build the Helpers */ while ((cd_item = (NET_cdataStruct *)XP_ListNextObject(infolist))) { if ( cd_item->ci.type && (int)strlen(cd_item->ci.type) >0 ) { /* Add this item to the list table */ if ( !fe_helpers_is_deleted_type(cd_item) ) { md = fe_helpers_get_mailcap_from_type(cd_item->ci.type); fe_helpers_append_type_to_list(fep, cd_item,md, item_count); item_count++; } } } XtVaSetValues( fep->helpers_list, XmNlayoutFrozen, False, NULL); } struct fe_prefs_helpers_data * fe_helpers_make_helpers_page (MWContext *context, Widget parent) { Arg av [50]; int ac; XmFontList fontList, labelFont/*, defaultLabelFont*/; short avgwidth, avgheight; Widget form, commands, table, b; Widget label1, frame1, form1; Dimension width; /* Initialization */ struct fe_prefs_helpers_data *fep = NULL; /* Helper data kept here */ fep = (struct fe_prefs_helpers_data *) malloc ( sizeof (struct fe_prefs_helpers_data)); memset (fep, 0, sizeof (struct fe_prefs_helpers_data)); fep->context = context; fep->helpers_selector = parent; /* Create the enclosing form */ ac = 0; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNresizePolicy, XmNONE); ac++; form = XmCreateForm (fep->helpers_selector, "helpers", av, ac); XtManageChild (form); fep->helpers_page = form; /* Create the frame and form for the helper files */ ac = 0; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++; frame1 = XmCreateFrame (form, "helperFrame", av, ac); ac = 0; form1 = XmCreateForm (frame1, "helperBox", av, ac); /* Create labels */ ac = 0; XtSetArg (av [ac], XmNchildType, XmFRAME_TITLE_CHILD); ac++; label1 = XmCreateLabelGadget (frame1, "helperBoxLabel", av, ac); XtVaGetValues(label1, XmNfontList, &labelFont, NULL); /* Create the widgets for the helper form */ ac = 0; XtSetArg(av[ac], XmNselectionPolicy, XmSELECT_BROWSE_ROW); ac++; XtSetArg(av[ac], XmNhorizontalSizePolicy, XmCONSTANT); ac++; XtSetArg(av[ac], XmNallowColumnResize, True); ac++; XtSetArg(av[ac], XmNcolumnSizePolicy, XmVARIABLE); ac++; table = fep->helpers_list = XmLCreateGrid(form1, "helperApp", av, ac); XtVaSetValues( fep->helpers_list, XmNlayoutFrozen, True, NULL); XmLGridAddColumns(fep->helpers_list, XmCONTENT, -1, 2 ); XtVaSetValues(fep->helpers_list, XmNrowType, XmHEADING, XmNcolumn, 0, XmNcellDefaults, True, /* XmNcellFontList, labelFont, */ XmNcolumnWidth, DEFAULT_COLUMN_WIDTH, XmNcellType, XmSTRING_CELL, XmNcellEditable, True, XmNcellAlignment, XmALIGNMENT_LEFT, NULL); /* Second Column */ XtVaSetValues(fep->helpers_list, XmNrowType, XmHEADING, XmNcolumn, 1, XmNcellDefaults, True, /* XmNcellFontList, labelFont, */ XmNcellType, XmSTRING_CELL, XmNcellEditable, True, XmNcolumnWidth, MAX_COLUMN_WIDTH, XmNcellAlignment, XmALIGNMENT_LEFT, NULL); XmLGridAddRows(fep->helpers_list, XmHEADING, -1, 1); XmLGridSetStrings(fep->helpers_list, XP_GetString(XFE_HELPERS_LIST_HEADER)); /* Get the font from *XmLGrid*fontList at this point. - XXX dp */ /* defaultLabelFont = fe_GetFont (context, 2, LO_FONT_FIXED); */ XtVaSetValues(fep->helpers_list, XmNcellDefaults, True, XmNcellType, XmSTRING_CELL, XmNcellEditable, False, /* XmNcellFontList, (defaultLabelFont? defaultLabelFont: NULL), */ XmNcellLeftBorderType, XmBORDER_NONE, XmNcellRightBorderType, XmBORDER_NONE, XmNcellTopBorderType, XmBORDER_NONE, XmNcellBottomBorderType, XmBORDER_NONE, XmNcellAlignment, XmALIGNMENT_LEFT, NULL); XtVaSetValues(fep->helpers_list, XmNlayoutFrozen, False, NULL); /* Create for Edit..., New, Delete Buttons */ ac = 0; XtSetArg (av [ac], XmNskipAdjust, True); ac++; XtSetArg (av [ac], XmNorientation, XmVERTICAL); ac++; XtSetArg (av [ac], XmNpacking, XmPACK_TIGHT); ac++; commands = XmCreateRowColumn(form1, "commands", av, ac); ac = 0; fep->edit_b = b = XmCreatePushButton(commands, "edit", av, ac); XtAddCallback(b, XmNactivateCallback, fe_helpers_edit_cb, fep); XtManageChild(b); ac = 0; fep->new_b = b = XmCreatePushButton(commands, "new", av, ac); XtAddCallback(b, XmNactivateCallback, fe_helpers_new_cb, fep); XtManageChild(b); ac = 0; fep->delete_b = b = XmCreatePushButton(commands, "delete", av, ac); XtAddCallback(b, XmNactivateCallback, fe_helpers_delete_cb, fep); XtManageChild(b); XtVaSetValues(commands, XmNleftAttachment, XmATTACH_NONE, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, NULL); XtVaSetValues(fep->helpers_list, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, commands, XmNbottomAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, NULL); XtManageChild(commands); /* Finally, manage the widgets in form1 */ XtManageChild(fep->helpers_list); XtManageChild (form1); XtManageChild (label1); XtManageChild(frame1); XtManageChild(form); /* Set up Column Width */ XtVaGetValues(fep->helpers_list, XmNfontList, &fontList, XmNwidth, &width, NULL); XmLFontListGetDimensions(fontList, &avgwidth, &avgheight, TRUE); return fep; } /* * fe_helpers_prepareForDestroy() * * When the prefs is going to destroy the helpers and free the fep, prefs * will call this. The purpose of this is to take the neccessary steps to * - free any internal data * - remove destroy callback that will access the fep */ void fe_helpers_prepareForDestroy(struct fe_prefs_helpers_data *fep) { /* If the edit dialog was up, then the destroy of pref will result in the * destroy of the edit dialog, that would inturn access the fep. * Prevent that. */ if (fep->editor) { /* Prevent destroy from accessing the fep as it will be freed */ XtRemoveCallback (fep->editor, XmNdestroyCallback, fe_helpers_destroy_cb, fep); /* Do whatever destroy of the helper edit dialog does like * freeing memory ect */ fe_helpers_destroy_cb(0, (XtPointer) fep, 0); } return; }