/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ /* mailattach.c --- Mail Attachment stuff goes here. Created: Dora Hsu, 6-May-96. */ #include "mozilla.h" #include "xfe.h" #include /* for _XfeHeight() */ /* for XP_GetString() */ #include #include "felocale.h" extern int XFE_INVALID_FILE_ATTACHMENT_IS_A_DIRECTORY; extern int XFE_INVALID_FILE_ATTACHMENT_NOT_READABLE; extern int XFE_INVALID_FILE_ATTACHMENT_DOESNT_EXIST; extern int XFE_DLG_OK; extern int XFE_DLG_CLEAR; extern int XFE_DLG_CANCEL; static char* fe_last_attach_type = NULL; static void fe_attachmentUpdate(struct fe_mail_attach_data* mad ) { const char* ptr; char *str = NULL; if ( mad && mad->comppane ) { mad->attachments[mad->nattachments].url = NULL; MSG_SetAttachmentList(mad->comppane, mad->attachments); ptr = MSG_GetCompHeader(mad->comppane, MSG_ATTACHMENTS_HEADER_MASK); if (ptr) { str = malloc(sizeof(char)*(strlen(ptr)+1)); strcpy(str, ptr); } if (str) free(str); } } static void fe_del_attachment(struct fe_mail_attach_data* mad, int pos) { if (pos > mad->nattachments) return; else XP_ASSERT(pos <= mad->nattachments); pos--; if (mad->attachments[pos].url) XP_FREE((char *)mad->attachments[pos].url); pos++; while (pos < mad->nattachments) { mad->attachments[pos-1] = mad->attachments[pos]; pos++; } mad->nattachments--; fe_attachmentUpdate(mad); } static void fe_add_attachmentData(struct fe_mail_attach_data *mad, const struct MSG_AttachmentData *data) { struct MSG_AttachmentData *m; char *name = (char *)data->url; XmString xmstr; if (!name || !*name) return; if (mad->nattachments >= XFE_MAX_ATTACHMENTS) return; else XP_ASSERT(mad->nattachments < XFE_MAX_ATTACHMENTS); xmstr = XmStringCreate(name, XmSTRING_DEFAULT_CHARSET); XmListAddItem(mad->list, xmstr, 0); m = &mad->attachments[mad->nattachments]; *m = *data; m->url = XP_STRDUP(data->url); mad->nattachments++; if (mad->nattachments == 1) XmListSelectPos(mad->list, 1, True); XmListSelectItem(mad->list, xmstr, TRUE); XmStringFree(xmstr); } static void fe_add_attachment(struct fe_mail_attach_data *mad, char *name) { struct MSG_AttachmentData m = {0}; Boolean b; XmString xmstr; if (!name || !*name) return; if(mad->nattachments >= XFE_MAX_ATTACHMENTS) return; else XP_ASSERT(mad->nattachments < XFE_MAX_ATTACHMENTS); xmstr = XmStringCreate(name, XmSTRING_DEFAULT_CHARSET); XmListAddItem(mad->list, xmstr, 0); XtVaGetValues (mad->text_p, XmNset, &b, 0); if (b) m.desired_type = TEXT_PLAIN; else { XtVaGetValues (mad->postscript_p, XmNset, &b, 0); if (b) m.desired_type = APPLICATION_POSTSCRIPT; } m.url = name; mad->attachments[mad->nattachments] = m; mad->nattachments++; fe_attachmentUpdate(mad); XmListSelectItem(mad->list, xmstr, TRUE); XmStringFree(xmstr); } /*********************************** * Location popup related routines * ***********************************/ static void fe_locationOk_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure; char *url = fe_GetTextField(mad->location_text); if (url && *url) fe_add_attachment(mad, url); else if (url) XtFree(url); XtUnmanageChild(mad->location_shell); } static void fe_locationClear_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure; fe_SetTextField (mad->location_text, ""); /* Focus on the text widget after this, since otherwise you have to click again. */ XmProcessTraversal (mad->location_text, XmTRAVERSE_CURRENT); } static void fe_locationCancel_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure; XtUnmanageChild(mad->location_shell); } static void fe_attach_make_location(struct fe_mail_attach_data *mad) { Arg av [20]; int ac; Visual *v = 0; Colormap cmap = 0; Cardinal depth = 0; Widget shell; Widget parent; Widget form; Widget label, location_label, location_text; Widget ok_button, clear_button, cancel_button; Widget kids [20]; int i; if (mad->location_shell) return; #ifdef dp_DEBUG fprintf(stderr, "Making attach_location widgets : fe_attach_make_location().\n"); #endif parent = CONTEXT_WIDGET(mad->context); XtVaGetValues (parent, 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], XmNallowShellResize, True); ac++; */ /* XtSetArg (av[ac], XmNtransientFor, parent); ac++; */ XtSetArg (av[ac], XmNautoUnmanage, False); ac++; XtSetArg (av[ac], XmNdeleteResponse, XmUNMAP); ac++; XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_MODELESS); ac++; shell = XmCreateTemplateDialog (parent, "location_popup", av, ac); fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_OK_BUTTON)); fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_CANCEL_BUTTON)); fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_DEFAULT_BUTTON)); fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_HELP_BUTTON)); ac = 0; ok_button = XmCreatePushButtonGadget (shell, XP_GetString(XFE_DLG_OK), av, ac); clear_button = XmCreatePushButtonGadget (shell, XP_GetString(XFE_DLG_CLEAR), av, ac); cancel_button = XmCreatePushButtonGadget (shell, XP_GetString(XFE_DLG_CANCEL), av, ac); ac = 0; form = XmCreateForm(shell, "form", av, ac); label = XmCreateLabelGadget( form, "label", av, ac); location_label = XmCreateLabelGadget( form, "locationLabel", av, ac); location_text = fe_CreateTextField( form, "locationText", av, ac); if (fe_globalData.nonterminal_text_translations) XtOverrideTranslations (location_text, fe_globalData. nonterminal_text_translations); XtVaSetValues (label, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, 0); XtVaSetValues (location_label, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, label, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_NONE, 0); XtVaSetValues (location_text, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, label, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, location_label, XmNrightAttachment, XmATTACH_FORM, 0); _XfeHeight(location_label) = _XfeHeight(location_text); XtAddCallback(ok_button, XmNactivateCallback, fe_locationOk_cb, mad); XtAddCallback(clear_button, XmNactivateCallback, fe_locationClear_cb, mad); XtAddCallback(cancel_button, XmNactivateCallback, fe_locationCancel_cb, mad); fe_HackDialogTranslations (form); mad->location_shell = shell; i = 0; kids[i++] = mad->location_text = location_text; kids[i++] = location_label; kids[i++] = label; XtManageChildren(kids, i); i = 0; kids[i++] = ok_button; kids[i++] = clear_button; kids[i++] = cancel_button; XtManageChildren(kids, i); XtManageChild(form); XtManageChild(shell); } /************************* * File Attachment popup * *************************/ static void fe_attachFile_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure; XmFileSelectionBoxCallbackStruct *sbc = (XmFileSelectionBoxCallbackStruct *) call_data; char *file; char *msg; switch (sbc->reason) { case XmCR_NO_MATCH: XBell (XtDisplay (widget), 0); break; case XmCR_OK: XmStringGetLtoR (sbc->value, XmSTRING_DEFAULT_CHARSET, &file); if (!fe_isFileExist(file)) { msg = PR_smprintf( XP_GetString( XFE_INVALID_FILE_ATTACHMENT_DOESNT_EXIST ), file); if (msg) { fe_Alert_2(XtParent(mad->file_shell), msg); XP_FREE(msg); } } else if (!fe_isFileReadable(file)) { msg = PR_smprintf( XP_GetString( XFE_INVALID_FILE_ATTACHMENT_NOT_READABLE ) , file); if (msg) { fe_Alert_2(XtParent(mad->file_shell), msg); XP_FREE(msg); } } else if (fe_isDir(file)) { msg = PR_smprintf( XP_GetString( XFE_INVALID_FILE_ATTACHMENT_IS_A_DIRECTORY ), file); if (msg) { fe_Alert_2(XtParent(mad->file_shell), msg); if (msg) XP_FREE(msg); } } else { fe_add_attachment(mad, file); XtUnmanageChild(mad->file_shell); } break; case XmCR_CANCEL: XtUnmanageChild(mad->file_shell); break; default: abort (); } } static void fe_attach_make_file(struct fe_mail_attach_data *mad) { char *text = 0; XmString xmpat, xmfile; char buf [1024]; Arg av [20]; int ac; Visual *v = 0; Colormap cmap = 0; Cardinal depth = 0; Widget shell; Widget parent; Widget fileb; Boolean dirp = False; if (mad->file_shell) return; #ifdef dp_DEBUG fprintf(stderr, "Making attach_file widgets : fe_attach_make_file().\n"); #endif parent = CONTEXT_WIDGET (mad->context); XtVaGetValues (parent, XtNvisual, &v, XtNcolormap, &cmap, XtNdepth, &depth, 0); /*** text = fe_GetTextField(text_field); text = fe_StringTrim (text); ***/ if (!text || !*text) { xmpat = 0; xmfile = 0; } else if (dirp) { if (text [strlen (text) - 1] == '/') text [strlen (text) - 1] = 0; PR_snprintf (buf, sizeof (buf), "%.900s/*", text); xmpat = XmStringCreateLtoR (buf, XmSTRING_DEFAULT_CHARSET); xmfile = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET); } else { char *f; if (text [strlen (text) - 1] == '/') PR_snprintf (buf, sizeof (buf), "%.900s/*", text); else PR_snprintf (buf, sizeof (buf), "%.900s", text); xmfile = XmStringCreateLtoR (buf, XmSTRING_DEFAULT_CHARSET); f = strrchr (text, '/'); if (f && f != text) *f = 0; PR_snprintf (buf, sizeof (buf), "%.900s/*", text); xmpat = XmStringCreateLtoR (buf, XmSTRING_DEFAULT_CHARSET); } if (text) free (text); ac = 0; XtSetArg (av[ac], XmNvisual, v); ac++; XtSetArg (av[ac], XmNdepth, depth); ac++; XtSetArg (av[ac], XmNcolormap, cmap); ac++; /* XtSetArg (av[ac], XmNallowShellResize, True); ac++;*/ XtSetArg (av[ac], XmNdeleteResponse, XmUNMAP); ac++; XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_MODELESS); ac++; shell = XmCreateDialogShell (parent, "fileBrowser_popup", av, ac); ac = 0; XtSetArg (av[ac], XmNfileTypeMask, (dirp ? XmFILE_DIRECTORY : XmFILE_REGULAR)); ac++; fileb = XmCreateFileSelectionBox (shell, "fileBrowser", av, ac); #ifdef NO_HELP fe_UnmanageChild_safe (XmSelectionBoxGetChild (fileb, XmDIALOG_HELP_BUTTON)); #endif if (xmpat) { XtVaSetValues (fileb, XmNdirMask, xmpat, 0); XtVaSetValues (fileb, XmNpattern, xmpat, 0); XmFileSelectionDoSearch (fileb, xmpat); XtVaSetValues (fileb, XmNdirSpec, xmfile, 0); XmStringFree (xmpat); XmStringFree (xmfile); } XtAddCallback(fileb, XmNnoMatchCallback, fe_attachFile_cb, mad); XtAddCallback(fileb, XmNokCallback, fe_attachFile_cb, mad); XtAddCallback(fileb, XmNcancelCallback, fe_attachFile_cb, mad); mad->file_shell = fileb; fe_HackDialogTranslations (fileb); fe_NukeBackingStore (fileb); XtManageChild (fileb); } static void fe_attach_doc_type_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure; int *poslist, npos; int attach_pos = -1; if (XmListGetSelectedPos(mad->list, &poslist, &npos)) { attach_pos = poslist[npos - 1] - 1; XP_FREE(poslist); } /* * my how intuitive, if the file is attach as siurce, desired type = NULL. */ XtVaSetValues (widget, XmNset, True, 0); if (widget == mad->text_p) { XtVaSetValues (mad->source_p, XmNset, False, 0); XtVaSetValues (mad->postscript_p, XmNset, False, 0); if (attach_pos >= 0) mad->attachments[attach_pos].desired_type = TEXT_PLAIN; } else if (widget == mad->source_p) { XtVaSetValues (mad->text_p, XmNset, False, 0); XtVaSetValues (mad->postscript_p, XmNset, False, 0); if (attach_pos >= 0) mad->attachments[attach_pos].desired_type = NULL; } else if (widget == mad->postscript_p) { XtVaSetValues (mad->source_p, XmNset, False, 0); XtVaSetValues (mad->text_p, XmNset, False, 0); if (attach_pos >= 0) mad->attachments[attach_pos].desired_type = APPLICATION_POSTSCRIPT; } else abort (); } #if 0 static void fe_attachDestroy_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure; int i; #ifdef dp_DEBUG fprintf(stderr, "fe_attachDestroy_cb()\n"); fprintf(stderr, "Destroying fe_mail_attach_data...\n"); #endif /* Free the list of attachments too */ for(i=0; inattachments; i++) { XP_FREE((char *)mad->attachments[i].url); } if (mad->location_shell) XtDestroyWidget(mad->location_shell); if (mad->file_shell) XtDestroyWidget(XtParent(mad->file_shell)); /* This should be an error ** CONTEXT_DATA(mad->context) ->mad = NULL; */ free (mad); } #endif #if 0 static void fe_attachCancel_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure; /* We dont need to delete all the attachments that we have as they will be deleted either the next time we show the attach window (or) when the message composition context gets destroyed */ XtUnmanageChild(mad->shell); if (mad->location_shell) XtUnmanageChild(mad->location_shell); if (mad->file_shell) XtUnmanageChild(mad->file_shell); } #endif #if 0 static void fe_attachOk_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure; const char* ptr; char *str = NULL; mad->attachments[mad->nattachments].url = NULL; MSG_SetAttachmentList(mad->comppane, mad->attachments); ptr = MSG_GetCompHeader(mad->comppane, MSG_ATTACHMENTS_HEADER_MASK); if ( ptr ) { str = malloc(sizeof(char)*(strlen(ptr)+1)); strcpy(str, ptr); } if (str) free(str); /* We dont need to delete all the attachments that we have as they will be deleted either the next time we show the attach window (or) when the message composition context gets destroyed */ XtUnmanageChild(mad->shell); if (mad->location_shell) XtUnmanageChild(mad->location_shell); if (mad->file_shell) XtUnmanageChild(mad->file_shell); } #endif static void fe_attach_location_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure; if (!mad->location_shell) fe_attach_make_location(mad); XtManageChild(mad->location_shell); XMapRaised(XtDisplay(mad->location_shell), XtWindow(mad->location_shell)); } static void fe_attach_file_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure; if (!mad->file_shell) fe_attach_make_file(mad); XtManageChild(mad->file_shell); XMapRaised(XtDisplay(mad->file_shell), XtWindow(mad->file_shell)); } static void fe_attach_delete_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure; int *poslist, npos; int i, pos; if (XmListGetSelectedPos(mad->list, &poslist, &npos)) { for(i=0; ilist, poslist[i]); fe_del_attachment(mad, poslist[i]); } /* * After deleting an item from the list, select the * previous item in the list (or the last if it was * the first.) */ pos = poslist[npos - 1] - 1; if (pos < 0) pos = 0; XmListSelectPos(mad->list, pos, TRUE); XP_FREE(poslist); } /* * If nothing left in the list selected, desensitize * the delete button. */ if (!XmListGetSelectedPos(mad->list, &poslist, &npos)) { XtVaSetValues(mad->delete_attach, XmNsensitive, False, 0); } else XP_FREE(poslist); } static void fe_attach_select_cb (Widget widget, XtPointer closure, XtPointer call_data) { struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure; XmListCallbackStruct *cbs = (XmListCallbackStruct *) call_data; const char *s; Widget which_w = 0; if (cbs->item_position > mad->nattachments) return; else XP_ASSERT(cbs->item_position <= mad->nattachments); s = mad->attachments[cbs->item_position-1].desired_type; if (!s || !*s) which_w = mad->source_p; else if (!XP_STRCMP(s, APPLICATION_POSTSCRIPT)) which_w = mad->postscript_p; else if (!XP_STRCMP(s, TEXT_PLAIN)) which_w = mad->text_p; if (which_w == 0) return; else XP_ASSERT (which_w != 0); fe_attach_doc_type_cb(which_w, (XtPointer)mad, (XtPointer)NULL); XtVaSetValues(mad->delete_attach, XmNsensitive, True, 0); } void fe_make_new_attach_list (MWContext *context) { fe_ContextData* data = CONTEXT_DATA(context); struct fe_mail_attach_data *mad = data->mad; const struct MSG_AttachmentData *list; int i; /* Free the existing list of attachments */ XmListDeleteAllItems(mad->list); for(i=0; inattachments; i++) { XP_FREE((char *)mad->attachments[i].url); } mad->comppane = data->comppane; mad->nattachments = 0; /* Refresh the list of attachments */ list = MSG_GetAttachmentList(mad->comppane); /* list = MSG_GetCompHeader(mad->comppane, MSG_ATTACHMENTS_HEADER_MASK); */ while (list && list->url != NULL) { fe_add_attachmentData(mad, list); list++; } } Widget fe_make_managed_attach_form(MWContext* context, Widget parent) { fe_ContextData* data = CONTEXT_DATA(context); Widget list; Widget messb; Widget attach_location, attach_file, delete_attach; Widget kids [50]; Arg av [20]; int ac; struct fe_mail_attach_data *mad = data->mad; Widget label; Widget text_p, source_p, postscript_p; Widget form; XP_ASSERT(context->type == MWContextMessageComposition); if (mad) { fe_make_new_attach_list(context); return NULL; } ac = 0; XtSetArg (av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg (av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg (av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; form = XmCreateForm (parent, "attachForm", av, ac); ac = 0; XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_WORK_AREA); ac++; XtSetArg (av[ac], XmNresizePolicy, XmRESIZE_GROW); ac++; messb = XmCreateMessageBox(form, "messagebox", av, ac); fe_UnmanageChild_safe(XmMessageBoxGetChild(messb, XmDIALOG_SEPARATOR)); fe_UnmanageChild_safe(XmMessageBoxGetChild(messb, XmDIALOG_OK_BUTTON)); fe_UnmanageChild_safe(XmMessageBoxGetChild(messb, XmDIALOG_CANCEL_BUTTON)); fe_UnmanageChild_safe(XmMessageBoxGetChild(messb, XmDIALOG_HELP_BUTTON)); ac = 0; list = XmCreateScrolledList(messb, "list", av, ac); attach_location = XmCreatePushButtonGadget(messb, "attachLocation", av, ac); attach_file = XmCreatePushButtonGadget(messb, "attachFile", av, ac); ac = 0; XtSetArg (av[ac], XmNsensitive, False); ac++; delete_attach = XmCreatePushButtonGadget(messb, "delete", av, ac); ac = 0; label = XmCreateLabelGadget (form, "label", av, ac); ac = 0; XtSetArg (av[ac], XmNset, False); ac++; source_p = XmCreateToggleButtonGadget (form, "sourceToggle", av, ac); text_p = XmCreateToggleButtonGadget (form, "textToggle", av, ac); postscript_p = XmCreateToggleButtonGadget (form, "postscriptToggle", av, ac); /* Making the attachments in such a way that the list would grow is the height of the dialog is increased */ XtVaSetValues (messb, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, 0); XtVaSetValues (label, XmNtopAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_NONE, 0); XtVaSetValues (source_p, XmNtopAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, XmNbottomWidget, label, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, label, XmNrightAttachment, XmATTACH_NONE, 0); XtVaSetValues (text_p, XmNtopAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, XmNbottomWidget, label, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, source_p, XmNrightAttachment, XmATTACH_NONE, 0); XtVaSetValues (postscript_p, XmNtopAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET, XmNbottomWidget, label, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, text_p, XmNrightAttachment, XmATTACH_NONE, 0); #ifdef dora_DEBUG fprintf(stderr, "Creating new fe_mail_attach_data...\n"); #endif data->mad = mad = (struct fe_mail_attach_data *) calloc (sizeof (struct fe_mail_attach_data), 1); mad->nattachments = 0; mad->context = context; mad->shell = 0; mad->list = list; XtManageChild(list); ac = 0; kids [ac++] = attach_location; kids [ac++] = mad->attach_file = attach_file; kids [ac++] = mad->delete_attach = delete_attach; XtManageChildren (kids, ac); ac = 0; kids [ac++] = messb; kids [ac++] = label; kids [ac++] = mad->source_p = source_p; kids [ac++] = mad->text_p = text_p; kids [ac++] = mad->postscript_p = postscript_p; XtManageChildren (kids, ac); XtManageChild (form); #if 0 XtAddCallback (ok_button, XmNactivateCallback, fe_attachOk_cb, mad); XtAddCallback (cancel_button, XmNactivateCallback, fe_attachCancel_cb, mad); #endif XtAddCallback (attach_location, XmNactivateCallback, fe_attach_location_cb, mad); XtAddCallback (attach_file, XmNactivateCallback, fe_attach_file_cb, mad); XtAddCallback (delete_attach, XmNactivateCallback, fe_attach_delete_cb, mad); XtAddCallback (list, XmNbrowseSelectionCallback, fe_attach_select_cb, mad); XtAddCallback (text_p, XmNvalueChangedCallback, fe_attach_doc_type_cb, mad); XtAddCallback (source_p, XmNvalueChangedCallback, fe_attach_doc_type_cb, mad); XtAddCallback (postscript_p, XmNvalueChangedCallback, fe_attach_doc_type_cb, mad); /* Remember the last attachment typed used. */ XtVaSetValues((fe_last_attach_type == NULL ? source_p : strcmp(fe_last_attach_type, TEXT_PLAIN) == 0 ? text_p : strcmp(fe_last_attach_type, APPLICATION_POSTSCRIPT) == 0 ? postscript_p : source_p), XmNset, True, 0); return form; } extern void fe_MailComposeWin_ActivateFolder(MWContext *, int pos); /* Prompts for attachment info. */ void fe_mailto_attach_dialog(MWContext* context) { #if 0 struct fe_mail_attach_data *mad = CONTEXT_DATA(context)->mad; const struct MSG_AttachmentData *list; int i; #endif XP_ASSERT(context->type == MWContextMessageComposition); fe_MailComposeWin_ActivateFolder(context,1); #if 0 if (!mad || !mad->shell) { /* fe_make_attach_dialog(context); */ mad = CONTEXT_DATA(context)->mad; } /* Free the existing list of attachments */ XmListDeleteAllItems(mad->list); for(i=0; inattachments; i++) { XP_FREE((char *)mad->attachments[i].url); } mad->nattachments = 0; /* Refresh the list of attachments */ list = MSG_GetAttachmentList(mad->comppane); while (list && list->url != NULL) { fe_add_attachmentData(mad, list); list++; } XtManageChild(mad->shell); XMapRaised(XtDisplay(mad->shell), XtWindow(mad->shell)); #endif return; } void fe_attach_dropfunc(Widget dropw, void* closure, fe_dnd_Event type, fe_dnd_Source* source, XEvent* event) { MWContext *compose_context; MWContext *src_context; const struct MSG_AttachmentData *old_list, *a; struct MSG_AttachmentData *new_list; Boolean sensitive_p = False; char **urls, **ss; const char *s; char *str = NULL; int old_count = 0; int new_count = 0; int i; if (type != FE_DND_DROP) return; compose_context = (MWContext *) closure; if (!compose_context) return; XP_ASSERT(compose_context->type == MWContextMessageComposition); if (compose_context->type != MWContextMessageComposition) return; XtVaGetValues(CONTEXT_DATA(compose_context)->mcAttachments, XmNsensitive, &sensitive_p, 0); if (!sensitive_p) { /* If the Attachments field is not sensitive, then that means that an attachment (or delivery?) is in progress, and bad things would happen were we to try and attach things right now. So just beep. */ XBell (XtDisplay (CONTEXT_WIDGET(compose_context)), 0); return; } src_context = fe_WidgetToMWContext((Widget) source->closure); if (!src_context) return; switch (src_context->type) { case MWContextMail: case MWContextNews: /* ###tw Should get a list of all the selected URLs from the mail/news window...*/ urls = 0; break; case MWContextBookmarks: /* #### Get a list of all the selected URLs out of the bookmarks window... */ urls = 0; break; default: XP_ASSERT(0); urls = 0; break; } if (!urls) { XBell (XtDisplay (CONTEXT_WIDGET(compose_context)), 0); return; } new_count = 0; for (ss = urls; *ss; ss++) new_count++; XP_ASSERT(new_count > 0); if (new_count <= 0) return; /* #### leaks `urls'; but it already asserted. */ old_list = MSG_GetAttachmentList(CONTEXT_DATA(compose_context)->comppane); old_count = 0; if (old_list) for (a = old_list; a->url; a++) old_count++; new_list = (struct MSG_AttachmentData *) XP_ALLOC(sizeof(struct MSG_AttachmentData) * (old_count + new_count + 1)); for (i = 0; i < old_count; i++) { XP_MEMSET(&new_list[i], 0, sizeof(new_list[i])); if (old_list[i].url) new_list[i].url = XP_STRDUP(old_list[i].url); if (old_list[i].desired_type) new_list[i].desired_type = XP_STRDUP(old_list[i].desired_type); if (old_list[i].real_type) new_list[i].real_type = XP_STRDUP(old_list[i].real_type); if (old_list[i].real_encoding) new_list[i].real_encoding = XP_STRDUP(old_list[i].real_encoding); if (old_list[i].real_name) new_list[i].real_name = XP_STRDUP(old_list[i].real_name); if (old_list[i].description) new_list[i].description = XP_STRDUP(old_list[i].description); if (old_list[i].x_mac_type) new_list[i].x_mac_type = XP_STRDUP(old_list[i].x_mac_type); if (old_list[i].x_mac_creator) new_list[i].x_mac_creator = XP_STRDUP(old_list[i].x_mac_creator); } if (new_count > 0) XP_MEMSET(new_list + old_count, 0, sizeof(struct MSG_AttachmentData) * (new_count + 1)); i = old_count; for (ss = urls; *ss; ss++) new_list[i++].url = *ss; MSG_SetAttachmentList(CONTEXT_DATA(compose_context)->comppane, new_list); for (i = 0; i < old_count; i++) { if (new_list[i].url) XP_FREE((char*)new_list[i].url); if (new_list[i].desired_type) XP_FREE((char*)new_list[i].desired_type); if (new_list[i].real_type) XP_FREE((char*)new_list[i].real_type); if (new_list[i].real_encoding) XP_FREE((char*)new_list[i].real_encoding); if (new_list[i].real_name) XP_FREE((char*)new_list[i].real_name); if (new_list[i].description) XP_FREE((char*)new_list[i].description); if (new_list[i].x_mac_type) XP_FREE((char*)new_list[i].x_mac_type); if (new_list[i].x_mac_creator) XP_FREE((char*)new_list[i].x_mac_creator); } XP_FREE (new_list); for (ss = urls; *ss; ss++) XP_FREE(*ss); XP_FREE(urls); /* Now they're attached; update the display. */ s = MSG_GetCompHeader(CONTEXT_DATA(compose_context)->comppane, MSG_ATTACHMENTS_HEADER_MASK); if (s) { str = malloc(sizeof(char)*(strlen(s)+1)); strcpy(str, s); } if (str) free(str); }