Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
870
cde/programs/dtmail/dtmail/ComposeCmds.C
Normal file
870
cde/programs/dtmail/dtmail/ComposeCmds.C
Normal file
@@ -0,0 +1,870 @@
|
||||
/*
|
||||
*+SNOTICE
|
||||
*
|
||||
* $TOG: ComposeCmds.C /main/11 1998/10/21 17:23:13 mgreess $
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special
|
||||
* restrictions in a confidential disclosure agreement between
|
||||
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
||||
* document outside HP, IBM, Sun, USL, SCO, or Univel without
|
||||
* Sun's specific written approval. This document and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
|
||||
#include <EUSCompat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(NEED_MMAP_WRAPPER)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <sys/mman.h>
|
||||
#if defined(NEED_MMAP_WRAPPER)
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <pwd.h>
|
||||
#include <Xm/Text.h>
|
||||
#include <Xm/FileSBP.h>
|
||||
#include <Xm/PushB.h>
|
||||
#include <Xm/ToggleB.h>
|
||||
#include <Xm/PushBG.h>
|
||||
#include <Xm/PanedW.h>
|
||||
#include <Xm/Form.h>
|
||||
#include <Dt/Dts.h>
|
||||
#include <Dt/Action.h>
|
||||
#include <DtMail/IO.hh>
|
||||
#include "RoamMenuWindow.h"
|
||||
#include "SendMsgDialog.h"
|
||||
#include "Undelete.hh"
|
||||
#include "RoamCmds.h"
|
||||
#include "ComposeCmds.hh"
|
||||
#include "Application.h"
|
||||
#include "RoamApp.h"
|
||||
#include "DtMailWDM.hh"
|
||||
#include "FindDialog.h"
|
||||
#include "MsgScrollingList.hh"
|
||||
#include "MsgHndArray.hh"
|
||||
#include "MemUtils.hh"
|
||||
#include "MailMsg.h"
|
||||
#include "EUSDebug.hh"
|
||||
#include "DtMailGenDialog.hh"
|
||||
#include "DtMailHelp.hh"
|
||||
#include <DtMail/DtMailError.hh>
|
||||
#include "Help.hh"
|
||||
#include <Dt/Help.h>
|
||||
#include "Attachment.h"
|
||||
#include "str_utils.h"
|
||||
|
||||
ComposeFamily::ComposeFamily(char *name,
|
||||
char *label,
|
||||
int active,
|
||||
RoamMenuWindow *window)
|
||||
: RoamCmd(name, label, active, window)
|
||||
{
|
||||
_parent = window;
|
||||
}
|
||||
|
||||
#ifndef CAN_INLINE_VIRTUALS
|
||||
ComposeFamily::~ComposeFamily( void )
|
||||
{
|
||||
}
|
||||
#endif /* ! CAN_INLINE_VIRTUALS */
|
||||
|
||||
// Append a formatted message to Compose's Text area.
|
||||
// This routine is essentially the same as MsgScollingList::display_message()
|
||||
// except for two major differences:
|
||||
// 1. No RoamMenuWindow reference (so that Compose can be standalone).
|
||||
// 2. Indent string can be used for "include" and "forward".
|
||||
void
|
||||
ComposeFamily::Display_entire_msg(DtMailMessageHandle msgno,
|
||||
SendMsgDialog *compose,
|
||||
char *format
|
||||
)
|
||||
{
|
||||
DtMailEnv error;
|
||||
|
||||
int num_bodyParts;
|
||||
DtMail::MailBox *mbox = _menuwindow->mailbox();
|
||||
DtMail::Message *msg = mbox->getMessage(error, msgno);
|
||||
DtMail::Envelope *env = msg->getEnvelope(error);
|
||||
DtMail::BodyPart *tmpBP = NULL;
|
||||
DtMailBuffer tmpBuffer;
|
||||
void *buffer = NULL;
|
||||
unsigned long size = 0;
|
||||
|
||||
Editor::InsertFormat ins_format = Editor::IF_NONE;
|
||||
Editor::BracketFormat brackets = Editor::BF_NONE;
|
||||
|
||||
// Do not need to wrap "include", "forward", and "indent" with
|
||||
// catgets().
|
||||
if ( strcmp(format, "include") == 0 ) {
|
||||
ins_format = Editor::IF_BRACKETED;
|
||||
brackets = Editor::BF_INCLUDE;
|
||||
} else if ( strcmp(format, "forward") == 0 ) {
|
||||
ins_format = Editor::IF_BRACKETED;
|
||||
brackets = Editor::BF_FORWARD;
|
||||
} else if ( strcmp(format, "indent") == 0 ) {
|
||||
ins_format = Editor::IF_INDENTED;
|
||||
}
|
||||
|
||||
// Get the editor to display the body of message with the appropriate
|
||||
// insert/bracket formatting.
|
||||
// We only include the first body part of the message. Attachments,
|
||||
// etc. are "FORWARD"-ed but not "INCLUDE"-ed
|
||||
|
||||
char * status_string;
|
||||
DtMailBoolean firstBPHandled =
|
||||
compose->get_editor()->textEditor()->set_message(
|
||||
msg,
|
||||
&status_string,
|
||||
Editor::HF_ABBREV,
|
||||
ins_format,
|
||||
brackets);
|
||||
|
||||
// Now need to handle the unhandled body parts of the message.
|
||||
|
||||
num_bodyParts = msg->getBodyCount(error);
|
||||
if (error.isSet()) {
|
||||
// do something
|
||||
}
|
||||
|
||||
if (strcmp(format, "forward") == 0) {
|
||||
// If the message has attachments, then let the attach pane
|
||||
// handle attachments but not the first bodyPart (which has
|
||||
// already been handled here).
|
||||
|
||||
if ((num_bodyParts > 1) || (!firstBPHandled)) {
|
||||
|
||||
tmpBP = msg->getFirstBodyPart(error);
|
||||
if (firstBPHandled) {
|
||||
// The first bodyPart has already been handled.
|
||||
// The others, beginning from the second, need to be parsed
|
||||
// and put into the attachPane.
|
||||
|
||||
compose->setInclMsgHnd(msg, TRUE);
|
||||
tmpBP = msg->getNextBodyPart(error, tmpBP);
|
||||
|
||||
} else {
|
||||
// The first bodyPart was not handled.
|
||||
// It may not have been of type text.
|
||||
// The attachment pane needs to handle all the bodyParts
|
||||
// beginning with the first.
|
||||
|
||||
compose->setInclMsgHnd(msg, FALSE);
|
||||
}
|
||||
|
||||
char *name;
|
||||
while (tmpBP != NULL) {
|
||||
tmpBP->getContents(
|
||||
error, (const void **) &tmpBuffer.buffer,
|
||||
&tmpBuffer.size,
|
||||
NULL,
|
||||
&name,
|
||||
NULL,
|
||||
NULL);
|
||||
if (error.isSet()) {
|
||||
// Do something
|
||||
}
|
||||
// It's possible for an attachment to not have a name.
|
||||
if (!name) {
|
||||
name = "NoName";
|
||||
}
|
||||
|
||||
compose->add_att(name, tmpBuffer);
|
||||
tmpBP = msg->getNextBodyPart(error, tmpBP);
|
||||
if (error.isSet()) {
|
||||
// do something
|
||||
}
|
||||
|
||||
if (strcmp(name, "NoName") != 0) {
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
if (error.isSet()) {
|
||||
|
||||
// do something
|
||||
}
|
||||
|
||||
// Need to call this after calling parseAttachments().
|
||||
|
||||
compose->get_editor()->manageAttachArea();
|
||||
|
||||
// This message has attachment and is being included/forwarded,
|
||||
// so need to fill the Compose Message Handle with attachment
|
||||
// BodyParts.
|
||||
// See function for further details.
|
||||
|
||||
// compose->updateMsgHndAtt();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the message has attachments, then let the attach pane
|
||||
// handle attachments but not the first bodyPart (which has
|
||||
// already been handled here).
|
||||
|
||||
if ((num_bodyParts > 1) || (!firstBPHandled))
|
||||
{
|
||||
char *att;
|
||||
Editor *editor = compose->get_editor()->textEditor();
|
||||
|
||||
att = GETMSG(
|
||||
DT_catd, 1, 255,
|
||||
"------------------ Attachments ------------------\n");
|
||||
|
||||
tmpBP = msg->getFirstBodyPart(error);
|
||||
if (firstBPHandled)
|
||||
tmpBP = msg->getNextBodyPart(error, tmpBP);
|
||||
|
||||
editor->append_to_contents(att, strlen(att));
|
||||
while (tmpBP != NULL)
|
||||
{
|
||||
editor->set_attachment(tmpBP, ins_format, brackets);
|
||||
tmpBP = msg->getNextBodyPart(error, tmpBP);
|
||||
if (error.isSet()) {
|
||||
// do something
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Leave it up to check point routine for update or do it now???
|
||||
compose->updateMsgHnd();
|
||||
}
|
||||
|
||||
void
|
||||
ComposeFamily::appendSignature(SendMsgDialog * compose)
|
||||
{
|
||||
DtMailEnv error;
|
||||
DtMail::Session * d_session = theRoamApp.session()->session();
|
||||
DtMail::MailRc * mail_rc = d_session->mailRc(error);
|
||||
|
||||
const char * value = NULL;
|
||||
mail_rc->getValue(error, "signature", &value);
|
||||
if (error.isSet()) {
|
||||
return;
|
||||
}
|
||||
|
||||
char * fullpath = d_session->expandPath(error, value);
|
||||
compose->get_editor()->textEditor()->append_to_contents(fullpath);
|
||||
if (NULL != fullpath)
|
||||
free((void*) fullpath);
|
||||
if (NULL != NULL)
|
||||
free((void*) value);
|
||||
|
||||
compose->get_editor()->textEditor()->set_to_top();
|
||||
}
|
||||
|
||||
char *
|
||||
ComposeFamily::valueToAddrString(DtMailValueSeq & value)
|
||||
{
|
||||
int max_len = 0;
|
||||
|
||||
for (int count = 0; count < value.length(); count++) {
|
||||
max_len += strlen(*(value[count]));
|
||||
}
|
||||
|
||||
char * str = new char[max_len + count + 1];
|
||||
str[0] = 0;
|
||||
|
||||
DtMailBoolean need_comma = DTM_FALSE;
|
||||
|
||||
for (int cat = 0; cat < value.length(); cat++)
|
||||
{
|
||||
DtMailValue * val = value[cat];
|
||||
DtMailAddressSeq *addr_seq = val->toAddress();
|
||||
|
||||
for (int ad = 0; ad < addr_seq->length(); ad++)
|
||||
{
|
||||
DtMailValueAddress * addr = (*addr_seq)[ad];
|
||||
|
||||
// Deal with mail address parser shortcomings
|
||||
if ( strcmp(addr->dtm_address, ",") == 0 )
|
||||
continue ;
|
||||
|
||||
if (need_comma) {
|
||||
strcat(str, ", ");
|
||||
}
|
||||
|
||||
need_comma = DTM_TRUE;
|
||||
|
||||
strcat(str, addr->dtm_address);
|
||||
}
|
||||
|
||||
delete addr_seq;
|
||||
}
|
||||
|
||||
return(str);
|
||||
}
|
||||
|
||||
|
||||
// Container menu "Compose==>New Message"
|
||||
ComposeCmd::ComposeCmd(
|
||||
char *name,
|
||||
char *label,
|
||||
int active,
|
||||
RoamMenuWindow *window
|
||||
) : ComposeFamily( name, label, active, window )
|
||||
{
|
||||
}
|
||||
|
||||
// Put up a blank compose window.
|
||||
void
|
||||
ComposeCmd::doit()
|
||||
{
|
||||
SendMsgDialog * newsend = theCompose.getWin();
|
||||
if (newsend == NULL) {
|
||||
DtMailGenDialog * dialog = _parent->genDialog();
|
||||
|
||||
dialog->setToErrorDialog(GETMSG(DT_catd, 1, 203, "Mailer"),
|
||||
GETMSG(DT_catd, 1, 204, "Unable to create a compose window."));
|
||||
char * helpId = DTMAILHELPNOCOMPOSE;
|
||||
int answer = dialog->post_and_return(helpId);
|
||||
}
|
||||
|
||||
appendSignature(newsend);
|
||||
}
|
||||
|
||||
// Container menu "Compose==>New, Include All" and "Compose==>Forward Message"
|
||||
// The last parameter is a switch for "include" or "forward" format.
|
||||
ForwardCmd::ForwardCmd(
|
||||
char *name,
|
||||
char *label,
|
||||
int active,
|
||||
RoamMenuWindow *window,
|
||||
int forward
|
||||
) : ComposeFamily(name, label, active, window)
|
||||
{
|
||||
_forward = forward;
|
||||
}
|
||||
|
||||
// Forward or Include selected messages.
|
||||
// For Include message(s), all Compose window header fields are left blank.
|
||||
// For Forward message(s), the Compose window "Subject" header field is filled
|
||||
// with the subject of the last selected message.
|
||||
void
|
||||
ForwardCmd::doit()
|
||||
{
|
||||
FORCE_SEGV_DECL(MsgHndArray, msgList);
|
||||
FORCE_SEGV_DECL(MsgStruct, tmpMS);
|
||||
DtMailMessageHandle msgno;
|
||||
|
||||
// Get a Compose window.
|
||||
SendMsgDialog *newsend = theCompose.getWin();
|
||||
if ( newsend == NULL ) {
|
||||
DtMailGenDialog * dialog = _parent->genDialog();
|
||||
|
||||
dialog->setToErrorDialog(GETMSG(DT_catd, 1, 205, "Mailer"),
|
||||
GETMSG(DT_catd, 1, 206, "Unable to create a compose window."));
|
||||
char * helpId = DTMAILHELPNOCOMPOSE;
|
||||
int answer = dialog->post_and_return(helpId);
|
||||
}
|
||||
|
||||
// Put the signature above the message.
|
||||
//
|
||||
appendSignature(newsend);
|
||||
|
||||
// For Forwarding subject
|
||||
DtMail::MailBox * mbox = _menuwindow->mailbox();
|
||||
DtMail::Message * msg;
|
||||
DtMail::Envelope * env;
|
||||
DtMailValueSeq value;
|
||||
DtMailEnv error;
|
||||
|
||||
// For each selected message, put it in the Compose window.
|
||||
if ( msgList = _menuwindow->list()->selected() ) {
|
||||
for ( int k = 0; k < msgList->length(); k++ ) {
|
||||
tmpMS = msgList->at(k);
|
||||
msgno = tmpMS->message_handle;
|
||||
if ( _forward ) {
|
||||
msg = mbox->getMessage(error, msgno);
|
||||
env = msg->getEnvelope(error);
|
||||
value.clear();
|
||||
env->getHeader(error, DtMailMessageSubject, DTM_TRUE, value);
|
||||
if (!error.isSet()) {
|
||||
const char *subject = *(value[0]);
|
||||
newsend->setHeader("Subject", subject);
|
||||
newsend->setTitle((char*) subject);
|
||||
newsend->setIconTitle((char*) subject);
|
||||
}
|
||||
Display_entire_msg(msgno, newsend, "forward");
|
||||
} else {
|
||||
Display_entire_msg(msgno, newsend, "indent");
|
||||
}
|
||||
}
|
||||
}
|
||||
newsend->get_editor()->textEditor()->set_to_top();
|
||||
}
|
||||
|
||||
// Container menu "Compose==>Reply to Semder" and
|
||||
// "Compose==>Reply to Sender, Include"
|
||||
// The last parameter is a switch for including the selected message or not.
|
||||
ReplyCmd::ReplyCmd (
|
||||
char *name,
|
||||
char *label,
|
||||
int active,
|
||||
RoamMenuWindow *window,
|
||||
int include
|
||||
) : ComposeFamily ( name, label, active, window )
|
||||
{
|
||||
_include = include;
|
||||
}
|
||||
|
||||
// For each message selected, reply to sender.
|
||||
void
|
||||
ReplyCmd::doit()
|
||||
{
|
||||
FORCE_SEGV_DECL(MsgHndArray, msgList);
|
||||
FORCE_SEGV_DECL(MsgStruct, tmpMS);
|
||||
DtMailMessageHandle msgno;
|
||||
FORCE_SEGV_DECL(char, from);
|
||||
FORCE_SEGV_DECL(char, subject);
|
||||
FORCE_SEGV_DECL(char, cc);
|
||||
DtMailEnv error;
|
||||
DtMail::MailBox * mbox = _menuwindow->mailbox();
|
||||
|
||||
// Initialize the error.
|
||||
error.clear();
|
||||
|
||||
if (msgList = _menuwindow->list()->selected())
|
||||
{
|
||||
for ( int i=0; i < msgList->length(); i++ ) {
|
||||
tmpMS = msgList->at(i);
|
||||
msgno = tmpMS->message_handle;
|
||||
SendMsgDialog *newsend = theCompose.getWin();
|
||||
if ( newsend == NULL ) {
|
||||
DtMailGenDialog * dialog = _parent->genDialog();
|
||||
|
||||
dialog->setToErrorDialog(GETMSG(DT_catd, 1, 207, "Mailer"),
|
||||
GETMSG(DT_catd, 1, 208, "Unable to create a compose window."));
|
||||
char * helpId = DTMAILHELPNOCOMPOSE;
|
||||
int answer = dialog->post_and_return(helpId);
|
||||
}
|
||||
XmUpdateDisplay( newsend->baseWidget() );
|
||||
|
||||
DtMail::Message * msg = mbox->getMessage(error, msgno);
|
||||
DtMail::Envelope * env = msg->getEnvelope(error);
|
||||
|
||||
DtMailValueSeq value;
|
||||
|
||||
env->getHeader(error, DtMailMessageSender, DTM_TRUE, value);
|
||||
if (error.isSet()) {
|
||||
newsend->setHeader("To", "nobody@nowhere");
|
||||
}
|
||||
else {
|
||||
char * addr_str = valueToAddrString(value);
|
||||
newsend->setHeader("To", addr_str);
|
||||
delete [] addr_str;
|
||||
}
|
||||
|
||||
value.clear();
|
||||
env->getHeader(error, DtMailMessageSubject, DTM_TRUE, value);
|
||||
if (error.isSet()) {
|
||||
subject = new char[200];
|
||||
strcpy(subject, "Re: ");
|
||||
DtMailValueSeq sent;
|
||||
env->getHeader(error,
|
||||
DtMailMessageSentTime,
|
||||
DTM_TRUE,
|
||||
sent);
|
||||
if (error.isSet()) {
|
||||
strcat(subject, "Your Message");
|
||||
}
|
||||
else {
|
||||
strcat(subject, "Your Message Sent on ");
|
||||
strcat(subject, *(sent[0]));
|
||||
}
|
||||
newsend->setHeader("Subject", subject);
|
||||
}
|
||||
else {
|
||||
// Get the BE store of header. It may contain newlines or
|
||||
// tab chars which can munge the scrolling list's display!
|
||||
|
||||
const char * orig = *(value[0]);
|
||||
|
||||
int fc;
|
||||
int orig_length;
|
||||
char *tmp_subj;
|
||||
|
||||
// Check if BE store contains the funky chars.
|
||||
|
||||
for (fc = 0, orig_length = strlen(orig),
|
||||
tmp_subj = (char *) orig;
|
||||
fc < orig_length;
|
||||
fc++, tmp_subj++) {
|
||||
|
||||
char c = *tmp_subj;
|
||||
if ((c == '\n')
|
||||
|| (c == '\t')
|
||||
|| (c == '\r')) {
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
subject = new char[fc+6];
|
||||
|
||||
if (strncasecmp(orig, "Re:", 3)) {
|
||||
strcpy(subject, "Re: ");
|
||||
}
|
||||
else {
|
||||
*subject = 0;
|
||||
}
|
||||
|
||||
strncat((char *)subject, orig, fc);
|
||||
|
||||
newsend->setHeader("Subject", subject);
|
||||
}
|
||||
|
||||
newsend->setTitle(subject);
|
||||
newsend->setIconTitle(subject);
|
||||
delete [] subject;
|
||||
|
||||
if ( _include ) {
|
||||
Display_entire_msg(msgno, newsend, "indent");
|
||||
newsend->get_editor()->textEditor()->set_to_top();
|
||||
}
|
||||
appendSignature(newsend);
|
||||
newsend->setInputFocus(1);
|
||||
}
|
||||
|
||||
delete msgList;
|
||||
}
|
||||
}
|
||||
|
||||
// Container menu "Compose==>Reply to All" and "Compose==>Reply to All, Include"
|
||||
// The last parameter is a switch for including the selected message or not.
|
||||
ReplyAllCmd::ReplyAllCmd(
|
||||
char *name,
|
||||
char *label,
|
||||
int active,
|
||||
RoamMenuWindow *window,
|
||||
int include
|
||||
) : ComposeFamily( name, label, active, window )
|
||||
{
|
||||
_include = include;
|
||||
}
|
||||
|
||||
// For each message selected, reply to everybody.
|
||||
void
|
||||
ReplyAllCmd::doit()
|
||||
{
|
||||
FORCE_SEGV_DECL(MsgHndArray, msgList);
|
||||
FORCE_SEGV_DECL(MsgStruct, tmpMS);
|
||||
FORCE_SEGV_DECL(char, subject);
|
||||
FORCE_SEGV_DECL(char, to);
|
||||
FORCE_SEGV_DECL(char, buffer);
|
||||
DtMailMessageHandle msgno;
|
||||
DtMail::MailBox *mbox = _menuwindow->mailbox();
|
||||
DtMailEnv error;
|
||||
char *currentCcValue;
|
||||
SendMsgDialog *newsend;
|
||||
DtMailGenDialog * dialog;
|
||||
DtMail::Message *msg;
|
||||
DtMail::Envelope *env;
|
||||
|
||||
|
||||
// Initialize the mail_error.
|
||||
error.clear();
|
||||
|
||||
|
||||
if ( msgList = _menuwindow->list()->selected() )
|
||||
for ( int k = 0; k < msgList->length(); k++ ) {
|
||||
DtMailValueSeq value ;
|
||||
|
||||
tmpMS = msgList->at(k);
|
||||
msgno = tmpMS->message_handle;
|
||||
newsend = theCompose.getWin();
|
||||
if ( newsend == NULL ) {
|
||||
dialog = _parent->genDialog();
|
||||
|
||||
dialog->setToErrorDialog(GETMSG(DT_catd, 1, 209, "Mailer"),
|
||||
GETMSG(DT_catd, 1, 210, "Unable to create a compose window."));
|
||||
char * helpId = DTMAILHELPNOCOMPOSE;
|
||||
int answer = dialog->post_and_return(helpId);
|
||||
}
|
||||
msg = mbox->getMessage(error, msgno);
|
||||
env = msg->getEnvelope(error);
|
||||
|
||||
env->getHeader(
|
||||
error,
|
||||
DtMailMessageToReply,
|
||||
DTM_TRUE,
|
||||
value);
|
||||
|
||||
env->getHeader(
|
||||
error,
|
||||
DtMailMessageSender,
|
||||
DTM_TRUE,
|
||||
value);
|
||||
|
||||
char * addr_str = valueToAddrString(value);
|
||||
newsend->setHeader("To", addr_str);
|
||||
delete [] addr_str;
|
||||
value.clear();
|
||||
env->getHeader(
|
||||
error,
|
||||
DtMailMessageSubject,
|
||||
DTM_TRUE,
|
||||
value);
|
||||
if ( error.isSet() ) {
|
||||
subject = new char[200];
|
||||
strcpy(subject, "Re: ");
|
||||
DtMailValueSeq sent;
|
||||
env->getHeader(error,
|
||||
DtMailMessageSentTime,
|
||||
DTM_TRUE,
|
||||
sent);
|
||||
if (error.isSet()) {
|
||||
strcat(subject, "Your Message");
|
||||
}
|
||||
else {
|
||||
strcat(subject, "Your Message Sent on ");
|
||||
strcat(subject, *(sent[0]));
|
||||
}
|
||||
newsend->setHeader("Subject", subject);
|
||||
} else {
|
||||
// Get the BE store of header. It may contain newlines or
|
||||
// tab chars which can munge the scrolling list's display!
|
||||
|
||||
const char * orig = *(value[0]);
|
||||
|
||||
|
||||
int fc = 0;
|
||||
int orig_length;
|
||||
char *tmp_subj;
|
||||
|
||||
// Check if BE store contains the funky chars.
|
||||
|
||||
for (fc = 0, orig_length = strlen(orig),
|
||||
tmp_subj = (char *)orig;
|
||||
fc < orig_length;
|
||||
fc++, tmp_subj++) {
|
||||
|
||||
char c = *tmp_subj;
|
||||
if ((c == '\n')
|
||||
|| (c == '\t')
|
||||
|| (c == '\r')) {
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
subject = new char[fc+6];
|
||||
|
||||
if (strncasecmp(orig, "Re:", 3)) {
|
||||
strcpy(subject, "Re: ");
|
||||
}
|
||||
else {
|
||||
*subject = 0;
|
||||
}
|
||||
|
||||
strncat((char *)subject, orig, fc);
|
||||
|
||||
newsend->setHeader("Subject", subject);
|
||||
}
|
||||
value.clear();
|
||||
env->getHeader(
|
||||
error,
|
||||
DtMailMessageCcReply,
|
||||
DTM_TRUE,
|
||||
value);
|
||||
if (!error.isSet()) {
|
||||
// Strip out newlines from the cc line. They *may* be
|
||||
// present.
|
||||
currentCcValue = valueToAddrString(value);
|
||||
|
||||
newsend->setHeader("Cc", currentCcValue);
|
||||
delete [] currentCcValue ;
|
||||
}
|
||||
|
||||
newsend->setTitle(subject);
|
||||
newsend->setIconTitle(subject);
|
||||
delete [] subject;
|
||||
|
||||
if ( _include ) {
|
||||
Display_entire_msg(msgno, newsend, "indent");
|
||||
newsend->get_editor()->textEditor()->set_to_top();
|
||||
}
|
||||
appendSignature(newsend);
|
||||
newsend->setInputFocus(1);
|
||||
}
|
||||
}
|
||||
|
||||
TemplateCmd::TemplateCmd(char *name,
|
||||
char *label,
|
||||
int active,
|
||||
SendMsgDialog * compose,
|
||||
const char * file)
|
||||
: NoUndoCmd(name, label, active)
|
||||
{
|
||||
_compose = compose;
|
||||
|
||||
if (*file != '/' && *file != '~') {
|
||||
// Relative path. Should be relative to home directory
|
||||
_file = (char *)malloc(strlen(file) + 4);
|
||||
if (_file != NULL) {
|
||||
strcpy(_file, "~/");
|
||||
strcat(_file, file);
|
||||
}
|
||||
} else {
|
||||
_file = strdup(file);
|
||||
}
|
||||
}
|
||||
|
||||
TemplateCmd::~TemplateCmd(void)
|
||||
{
|
||||
free(_file);
|
||||
}
|
||||
|
||||
void
|
||||
TemplateCmd::doit()
|
||||
{
|
||||
DtMailEnv error;
|
||||
DtMail::Session * d_session = theRoamApp.session()->session();
|
||||
DtMailGenDialog * dialog = _compose->genDialog();
|
||||
DtMailBuffer mbuf;
|
||||
|
||||
char * fullpath = d_session->expandPath(error, _file);
|
||||
|
||||
// Map the file and try to parse it as a message. If it is a message,
|
||||
// then load it with headers. Otherwise, throw everything into the
|
||||
// editor.
|
||||
//
|
||||
int fd = SafeOpen(fullpath, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
dialog->setToErrorDialog(GETMSG(DT_catd, 1, 211, "Mailer"),
|
||||
GETMSG(DT_catd, 1, 212, "The template does not exist."));
|
||||
char * helpId = DTMAILHELPNOTEMPLATE;
|
||||
int answer = dialog->post_and_return(helpId);
|
||||
free(fullpath);
|
||||
return;
|
||||
}
|
||||
|
||||
struct stat buf;
|
||||
if (SafeFStat(fd, &buf) < 0) {
|
||||
dialog->setToErrorDialog(GETMSG(DT_catd, 1, 213, "Mailer"),
|
||||
GETMSG(DT_catd, 1, 214, "The template appears to be corrupt."));
|
||||
char * helpId = DTMAILHELPCORRUPTTEMPLATE;
|
||||
int answer = dialog->post_and_return(helpId);
|
||||
SafeClose(fd);
|
||||
free(fullpath);
|
||||
return;
|
||||
}
|
||||
|
||||
int page_size = (int)sysconf(_SC_PAGESIZE);
|
||||
size_t map_size = (size_t) (buf.st_size +
|
||||
(page_size - (buf.st_size % page_size)));
|
||||
|
||||
int free_buf = 0;
|
||||
mbuf.size = buf.st_size;
|
||||
#ifdef __osf__
|
||||
// This version of mmap does NOT allow requested length to be
|
||||
// greater than the file size ... in contradiction to the
|
||||
// documentation (don't round up).
|
||||
mbuf.buffer = mmap(0, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
#else
|
||||
mbuf.buffer = mmap(0, map_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
#endif
|
||||
if (mbuf.buffer == (char *)-1) {
|
||||
free_buf = 1;
|
||||
mbuf.buffer = new char[mbuf.size];
|
||||
if (mbuf.buffer == NULL) {
|
||||
dialog->setToErrorDialog(GETMSG(DT_catd, 1, 215, "Mailer"),
|
||||
GETMSG(DT_catd, 1, 216, "There is not enough memory to load the template."));
|
||||
char * helpId = DTMAILHELPNOMEMTEMPLATE;
|
||||
int answer = dialog->post_and_return(helpId);
|
||||
SafeClose(fd);
|
||||
free(fullpath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SafeRead(fd, mbuf.buffer, (unsigned int)mbuf.size) < mbuf.size) {
|
||||
dialog->setToErrorDialog(GETMSG(DT_catd, 1, 217, "Mailer"),
|
||||
GETMSG(DT_catd, 1, 218, "The template appears to be corrupt."));
|
||||
char * helpId = DTMAILHELPERROR;
|
||||
int answer = dialog->post_and_return(helpId);
|
||||
SafeClose(fd);
|
||||
delete [] mbuf.buffer;
|
||||
free(fullpath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we ask the library to parse it. If this fails for any reason, this
|
||||
// is not a message, so we give up.
|
||||
//
|
||||
DtMail::Message * msg = d_session->messageConstruct(error,
|
||||
DtMailBufferObject,
|
||||
&mbuf,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (error.isSet()) {
|
||||
_compose->get_editor()->textEditor()->append_to_contents((char *)mbuf.buffer,
|
||||
mbuf.size);
|
||||
}
|
||||
else {
|
||||
_compose->loadHeaders(msg, DTM_TRUE);
|
||||
|
||||
DtMail::BodyPart * bp = msg->getFirstBodyPart(error);
|
||||
if (error.isNotSet()) {
|
||||
const void * contents;
|
||||
unsigned long length;
|
||||
|
||||
bp->getContents(error,
|
||||
&contents,
|
||||
&length,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
_compose->get_editor()->textEditor()->append_to_contents(
|
||||
(char *)contents, length);
|
||||
}
|
||||
}
|
||||
|
||||
free(fullpath);
|
||||
|
||||
if (free_buf) {
|
||||
free(mbuf.buffer);
|
||||
}
|
||||
else {
|
||||
munmap((char *)mbuf.buffer, map_size);
|
||||
}
|
||||
|
||||
SafeClose(fd);
|
||||
}
|
||||
|
||||
HideShowCmd::HideShowCmd(char *name,
|
||||
char *widgetlabel,
|
||||
int active,
|
||||
SendMsgDialog * compose,
|
||||
const char * label)
|
||||
: NoUndoCmd(name, (char *)widgetlabel, active)
|
||||
{
|
||||
_compose = compose;
|
||||
_header = strdup(label);
|
||||
}
|
||||
|
||||
HideShowCmd::~HideShowCmd(void)
|
||||
{
|
||||
if (_header) {
|
||||
free(_header);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HideShowCmd::doit(void)
|
||||
{
|
||||
_compose->changeHeaderState(_header);
|
||||
}
|
||||
Reference in New Issue
Block a user