1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00
cde/cde/programs/dtmail/dtmail/Editor.C
2018-04-28 12:30:20 -06:00

468 lines
12 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
*+SNOTICE
*
* $TOG: Editor.C /main/11 1998/07/24 16:06:00 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 <Xm/RowColumn.h>
#include <EUSCompat.h>
#include <assert.h>
#include <stdio.h>
#include <Dt/Dts.h>
#include "RoamApp.h"
#include "MailMsg.h"
#include "Editor.hh"
#include "str_utils.h"
Editor::Editor()
: UIComponent("Editor")
{
}
Editor::~Editor()
{
}
AbstractEditorParent::AbstractEditorParent() {
_attachmentPopupMenu = NULL;
_textPopupMenu = NULL;
_menuPopupAtt = NULL;
_menuPopupText = NULL;
}
AbstractEditorParent::~AbstractEditorParent()
{
delete _menuPopupAtt;
delete _menuPopupText;
}
DtMailBoolean
Editor::set_message(DtMail::Message * msg,
char ** status_string,
HeaderFormat header_format,
InsertFormat format,
BracketFormat brackets)
{
DtMailEnv error;
DtMail::Session *m_session = theRoamApp.session()->session();
DtMail::MailRc * mail_rc = m_session->mailRc(error);
*status_string = NULL;
DtMail::Envelope *env = msg->getEnvelope(error);
DtMailHeaderHandle hdr_hnd;
char *name;
DtMailValueSeq value;
// Here is not the place for getting the indent string
// but it'll do for now.
const char *indent_str = NULL;
mail_rc->getValue(error, "indentprefix", &indent_str);
if (error.isSet())
indent_str = strdup("> ");
disable_redisplay();
int indent = 0;
if (format == IF_BRACKETED) {
char * ins_bracket;
switch (brackets) {
case BF_FORWARD:
ins_bracket = GETMSG(DT_catd, 1, 195, "------------- Begin Forwarded Message -------------\n\n");
break;
case BF_INCLUDE:
default:
ins_bracket = GETMSG(DT_catd, 1, 196, "------------- Begin Included Message -------------\n\n");
break;
}
append_to_contents(ins_bracket, strlen(ins_bracket));
}
// Code from MsgScrollingList - display_message().
// We're trying to reduce heap size by not allocating and
// deleting space in every loop iteration. So just have a
// fixed size buffer initially.
//
// Initial line size. When not enough, allocate more.
int line_size = 1024;
int tmp_count = 0;
char *line = new char[line_size];
int hdr_num = 0;
if (header_format != HF_NONE) {
for ( hdr_hnd = env->getFirstHeader(
error,
&name,
value);
hdr_hnd && !error.isSet();
hdr_hnd = env->getNextHeader(
error,
hdr_hnd,
&name,
value), hdr_num++ ) {
if ((header_format == HF_ABBREV)
&& (hdr_num != 0 || strcmp(name, "From") != 0)) {
DtMailEnv ierror;
if (mail_rc->ignore(ierror, name)) {
free(name);
value.clear();
continue;
}
}
for ( int val = 0; val < value.length(); val++ ) {
tmp_count = strlen(name) +
strlen(*(value[val])) +
strlen(indent_str) +
5;
if ( tmp_count > line_size ) { // Need to increase line size.
delete [] line;
line_size = tmp_count;
line = new char[line_size];
}
memset(line, 0, line_size);
if (format == IF_INDENTED) {
strcpy(line, indent_str);
strcat(line, name);
} else {
strcpy(line, name);
}
if (hdr_num != 0 || strcmp(name, "From") != 0) {
strcat(line, ": ");
}
else {
strcat(line, " ");
}
strcat(line, *(value[val]));
strcat(line, "\n");
append_to_contents(line, strlen(line));
}
value.clear();
free(name);
}
}
// Don't delete line yet, because it's used below.
if (format == IF_INDENTED) {
append_to_contents(indent_str, strlen(indent_str));
}
if (header_format != HF_NONE) {
append_to_contents("\n", 1);
}
DtMail::BodyPart *bp = msg->getFirstBodyPart(error);
char *type;
DtMailBoolean firstBPHandled = DTM_FALSE;
bp->getContents(error, NULL, NULL, &type, NULL, NULL, NULL);
if ( type ) {
char *attr = DtDtsDataTypeToAttributeValue(
type,
DtDTS_DA_IS_TEXT,
NULL);
if ((attr && strcasecmp(attr, "true") == 0)
|| strcoll(type, DtDTS_DT_UNKNOWN) == 0 ) {
const void *contents;
unsigned long size;
bp->lockContents(error, DtMailLockRead);
bp->getContents(error, &contents, &size, NULL, NULL, NULL, NULL);
if (format == IF_INDENTED) {
int byte_count = 0;
int content_count = (int) size;
const char *last = NULL, *content_ptr = NULL;
// Parse the result of getContents().
// Spit out indent string with each line.
// Is contents NULL terminated???
for ( last = (const char *)contents,
content_ptr = (const char *)contents;
content_count > 0;
content_ptr++,
byte_count++,
content_count-- ) {
if ((*content_ptr == '\n') ||
(content_count == 1) ) {
// 2 for null terminator and new line.
tmp_count = strlen(indent_str) + byte_count + 2;
if ( tmp_count > line_size ) {
// Need to increase line size.
delete [] line;
line_size = tmp_count;
line = new char[line_size];
}
memset(line, 0, line_size);
strcpy(line, indent_str);
strncat(line, last, byte_count + 1);
// Copy the '\n' also
append_to_contents(line, strlen(line));
last = content_ptr + 1;
byte_count = -1;
}
} // end of for loop
} else {
append_to_contents((const char *)contents, size);
}
bp->unlockContents(error);
firstBPHandled = DTM_TRUE;
}
if (attr) {
DtDtsFreeAttributeValue(attr);
attr = NULL;
}
free(type);
// DLP: We will turn off this test for now. We need to study the problem
// of text checksums more.
//
//if (bp->checksum(error) == DtMailCheckBad) {
// *status_string = GETMSG(DT_catd, 1, -1, "Digital signature did not match.");
//}
}
delete [] line;
if (format == IF_BRACKETED) {
char * ins_bracket;
switch (brackets) {
case BF_FORWARD:
ins_bracket = GETMSG(DT_catd, 1, 197, "------------- End Forwarded Message -------------\n\n");
break;
case BF_INCLUDE:
default:
ins_bracket = GETMSG(DT_catd, 1, 198, "------------- End Included Message -------------\n\n");
break;
}
append_to_contents(ins_bracket, strlen(ins_bracket));
}
enable_redisplay();
if (NULL != indent_str)
free((void*) indent_str);
return(firstBPHandled);
}
void
Editor::append_newline_to_contents()
{
append_to_contents("\n", strlen("\n"));
}
void
Editor::set_attachment(
DtMail::BodyPart *bp,
InsertFormat format,
BracketFormat brackets)
{
DtMailEnv error;
DtMail::Session *m_session = theRoamApp.session()->session();
DtMail::MailRc * mail_rc = m_session->mailRc(error);
DtMailValueSeq value;
char *input, *name, *dttype, *description, *mimetype;
const char *indent_str = NULL;
unsigned long len;
if (format == IF_INDENTED)
{
mail_rc->getValue(error, "indentprefix", &indent_str);
if (error.isSet())
indent_str = strdup("> ");
}
disable_redisplay();
if ((format == IF_BRACKETED) && (brackets == BF_INCLUDE))
{
char * ins_bracket =
GETMSG(
DT_catd, 1, 249,
"------------- Begin Included Attachment -------------\n\n");
append_to_contents(ins_bracket, strlen(ins_bracket));
}
else if (format == IF_INDENTED)
{
append_to_contents(indent_str, strlen(indent_str));
append_newline_to_contents();
}
bp->getContents(error, NULL, &len, &dttype, &name, NULL, &description);
if ((NULL != name) && (0 != strlen(name)))
{
if (NULL != indent_str)
append_to_contents(indent_str, strlen(indent_str));
input = GETMSG(DT_catd, 1, 251, " Attachment Name: ");
append_to_contents(input, strlen(input));
append_to_contents(name, strlen(name));
append_newline_to_contents();
}
if ((NULL != dttype) && (0 != strlen(dttype)))
{
if (NULL != indent_str)
append_to_contents(indent_str, strlen(indent_str));
input = GETMSG(DT_catd, 1, 252, " Attachment DtType: ");
append_to_contents(input, strlen(input));
append_to_contents(dttype, strlen(dttype));
append_newline_to_contents();
}
bp->getContentType(error, &mimetype);
if ((NULL != mimetype) && (0 != strlen(mimetype)))
{
if (NULL != indent_str)
append_to_contents(indent_str, strlen(indent_str));
input = GETMSG(DT_catd, 1, 253, "Attachment ContentType: ");
append_to_contents(input, strlen(input));
append_to_contents(mimetype, strlen(mimetype));
append_newline_to_contents();
}
if ((NULL != description) && (0 != strlen(description)))
{
if (NULL != indent_str)
append_to_contents(indent_str, strlen(indent_str));
input = GETMSG(DT_catd, 1, 254, "Attachment Description: ");
append_to_contents(input, strlen(input));
append_to_contents(description, strlen(description));
append_newline_to_contents();
}
if ((format == IF_BRACKETED) && (brackets == BF_INCLUDE))
{
char * ins_bracket =
GETMSG(
DT_catd, 1, 250,
"------------- End Included Attachment -------------\n\n");
append_to_contents(ins_bracket, strlen(ins_bracket));
}
else if (format == IF_INDENTED)
{
append_to_contents(indent_str, strlen(indent_str));
append_newline_to_contents();
}
enable_redisplay();
if (NULL != indent_str)
free((void*) indent_str);
if (NULL != name)
free((void*) name);
if (NULL != dttype)
free((void*) dttype);
if (NULL != mimetype)
free((void*) mimetype);
if (NULL != description)
free((void*) description);
}
void
Editor::update_display_from_props(void)
{
int rows, cols;
DtMailEnv error;
DtMail::Session * d_session = theRoamApp.session()->session();
DtMail::MailRc * mailrc = d_session->mailRc(error);
const char * value = NULL;
mailrc->getValue(error, "popuplines", &value);
if (error.isSet()) {
value = strdup("24");
}
rows = (int) strtol(value, NULL, 10);
free((void*) value);
set_rows(rows);
// If toolcols is set, overwrite the column width with "toolcols" value.
// Otherwise, default resource value will be used.
value = NULL;
error.clear();
mailrc->getValue(error, "toolcols", &value);
if (!error.isSet()){
cols = (int) strtol(value, NULL, 10);
free((void*) value);
} else {
/*
* MB_CUR_MAX == 1 : SingleByteLanguage
* MB_CUR_MAX > 1 : MultiByteLanguage
*/
if ( MB_CUR_MAX == 1 )
cols = 80;
else
cols = 40;
}
set_columns(cols);
}
void
AbstractEditorParent::postAttachmentPopup(XEvent *event)
{
XmMenuPosition(_attachmentPopupMenu, (XButtonEvent *)event);
XtManageChild(_attachmentPopupMenu);
}
void
AbstractEditorParent::postTextPopup(XEvent *event)
{
if (_textPopupMenu == NULL)
return;
XmMenuPosition(_textPopupMenu, (XButtonEvent *)event);
XtManageChild(_textPopupMenu);
}