4172 lines
87 KiB
C
4172 lines
87 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: RoamCmds.C /main/43 1999/07/13 08:41:44 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, 1994, 1995 Sun Microsystems, Inc. All rights reserved.
|
|
*
|
|
*+ENOTICE
|
|
*/
|
|
/*
|
|
* Common Desktop Environment
|
|
*
|
|
* (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
|
|
* (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
|
|
* (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
|
|
* (c) Copyright 1993, 1994, 1995 Novell, Inc.
|
|
* (c) Copyright 1995 Digital Equipment Corp.
|
|
* (c) Copyright 1995 Fujitsu Limited
|
|
* (c) Copyright 1995 Hitachi, Ltd.
|
|
*
|
|
*
|
|
* RESTRICTED RIGHTS LEGEND
|
|
*
|
|
*Use, duplication, or disclosure by the U.S. Government is subject to
|
|
*restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
|
|
*Technical Data and Computer Software clause in DFARS 252.227-7013. Rights
|
|
*for non-DOD U.S. Government Departments and Agencies are as set forth in
|
|
*FAR 52.227-19(c)(1,2).
|
|
|
|
*Hewlett-Packard Company, 3000 Hanover Street, Palo Alto, CA 94304 U.S.A.
|
|
*International Business Machines Corp., Route 100, Somers, NY 10589 U.S.A.
|
|
*Sun Microsystems, Inc., 2550 Garcia Avenue, Mountain View, CA 94043 U.S.A.
|
|
*Novell, Inc., 190 River Road, Summit, NJ 07901 U.S.A.
|
|
*Digital Equipment Corp., 111 Powdermill Road, Maynard, MA 01754, U.S.A.
|
|
*Fujitsu Limited, 1015, Kamikodanaka Nakahara-Ku, Kawasaki 211, Japan
|
|
*Hitachi, Ltd., 6, Kanda Surugadai 4-Chome, Chiyoda-ku, Tokyo 101, Japan
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <sys/param.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <stdint.h>
|
|
#include <pwd.h>
|
|
#include <X11/Intrinsic.h>
|
|
#include <Xm/Text.h>
|
|
#include <Xm/FileSBP.h>
|
|
#include <Xm/FileSB.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 <Dt/Help.h>
|
|
#include <Dt/DtPStrings.h>
|
|
|
|
#include <DtMail/IO.hh>
|
|
#include <DtMail/DtMailError.hh>
|
|
#ifndef __ppc
|
|
#include <DtMail/Buffer.hh>
|
|
#endif
|
|
#ifdef __ppc
|
|
#include <DtMail/Buffer.hh>
|
|
#endif
|
|
#include <DtMail/OptCmd.h>
|
|
#include <EUSCompat.h>
|
|
#include "EUSDebug.hh"
|
|
#include "Application.h"
|
|
#include "AttachArea.h"
|
|
#include "Attachment.h"
|
|
#include "Dmx.h"
|
|
#include "DmxPrintJob.h"
|
|
#include "DtMailEditor.hh"
|
|
#include "DtMailGenDialog.hh"
|
|
#include "DtMailHelp.hh"
|
|
#include "DtMailWDM.hh"
|
|
#include "FindDialog.h"
|
|
#include "Help.hh"
|
|
#include "MailMsg.h"
|
|
#include "MemUtils.hh"
|
|
#include "MsgScrollingList.hh"
|
|
#include "MsgHndArray.hh"
|
|
#include "RoamApp.h"
|
|
#include "RoamCmds.h"
|
|
#include "RoamMenuWindow.h"
|
|
#include "SendMsgDialog.h"
|
|
#include "Undelete.hh"
|
|
|
|
#if defined(NEED_MMAP_WRAPPER)
|
|
extern "C" {
|
|
#endif
|
|
#include <sys/mman.h>
|
|
#if defined(NEED_MMAP_WRAPPER)
|
|
}
|
|
#endif
|
|
|
|
extern "C" {
|
|
extern XtPointer _XmStringUngenerate (
|
|
XmString string,
|
|
XmStringTag tag,
|
|
XmTextType tag_type,
|
|
XmTextType output_type);
|
|
}
|
|
|
|
|
|
#include <sys/file.h>
|
|
|
|
|
|
extern void forceUpdate( Widget );
|
|
|
|
RoamCmd::RoamCmd
|
|
(char *name, char *label, int active, RoamMenuWindow *window)
|
|
: NoUndoCmd (name, label, active)
|
|
{
|
|
_menuwindow = window;
|
|
}
|
|
|
|
#ifdef DEAD_WOOD
|
|
SearchCmd::SearchCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : InterruptibleCmd (name, label, active)
|
|
{
|
|
_menuwindow = window;
|
|
_criteria = NULL;
|
|
}
|
|
|
|
void
|
|
SearchCmd::execute (
|
|
TaskDoneCallback callback,
|
|
void *clientData
|
|
)
|
|
{
|
|
InterruptibleCmd::execute( callback, clientData );
|
|
}
|
|
|
|
void
|
|
SearchCmd::execute()
|
|
{
|
|
|
|
_menuwindow->list()->clearMsgs();
|
|
_menuwindow->busyCursor();
|
|
|
|
if ( !_criteria ) {
|
|
_criteria=( char * )realloc(_criteria, strlen( this->name()) + 1);
|
|
strcpy(_criteria, this->name());
|
|
}
|
|
|
|
InterruptibleCmd::execute();
|
|
}
|
|
|
|
void
|
|
SearchCmd::doit()
|
|
{
|
|
int count;
|
|
DtMailEnv mail_error;
|
|
|
|
// Initialize the mail_error.
|
|
mail_error.clear();
|
|
|
|
MsgScrollingList *list=_menuwindow->list();
|
|
|
|
|
|
// load_headers will retrieve all of the message headers and
|
|
// add the handles to the list.
|
|
//
|
|
count = list->load_headers(mail_error);
|
|
|
|
_menuwindow->normalCursor();
|
|
|
|
if (count == 0) {
|
|
_menuwindow->message(GETMSG(DT_catd, 3, 46, "Empty container"));
|
|
_done = TRUE;
|
|
return;
|
|
}
|
|
|
|
list->scroll_to_bottom();
|
|
_done=TRUE;
|
|
}
|
|
|
|
void
|
|
SearchCmd::undoit()
|
|
{
|
|
// Just print a message that allows us to trace the execution
|
|
|
|
DebugPrintf(1, "%s: undoit\n", name());
|
|
}
|
|
|
|
void
|
|
SearchCmd::updateMessage (char *msg)
|
|
{
|
|
InterruptibleCmd::updateMessage(msg);
|
|
}
|
|
#endif /* DEAD_WOOD */
|
|
|
|
CheckForNewMailCmd::CheckForNewMailCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : NoUndoCmd ( name, label, active )
|
|
{
|
|
_menuwindow = window;
|
|
}
|
|
|
|
void
|
|
CheckForNewMailCmd::doit()
|
|
{
|
|
DtMailEnv error;
|
|
// Initialize the mail_error.
|
|
error.clear();
|
|
_menuwindow->checkForMail(error);
|
|
|
|
}
|
|
|
|
OpenInboxCmd::OpenInboxCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *rmw
|
|
) : Cmd (name, label, active)
|
|
{
|
|
|
|
_menuWindow = rmw;
|
|
|
|
}
|
|
|
|
void
|
|
OpenInboxCmd::doit()
|
|
{
|
|
RoamMenuWindow *rmw = theRoamApp.inboxWindow();
|
|
|
|
if (rmw)
|
|
{
|
|
MailSession *ses = theRoamApp.session();
|
|
ses->activateRMW(rmw);
|
|
rmw->manage();
|
|
}
|
|
else
|
|
{
|
|
DtMailEnv mail_error;
|
|
char *mail_file = NULL;
|
|
DtMailObjectSpace space;
|
|
DtMail::Session *d_session = theRoamApp.session()->session();
|
|
|
|
mail_error.clear();
|
|
d_session->queryImpl(mail_error,
|
|
d_session->getDefaultImpl(mail_error),
|
|
DtMailCapabilityInboxName,
|
|
&space,
|
|
&mail_file);
|
|
|
|
// Check for error
|
|
if (mail_file) _menuWindow->view_mail_file(mail_file, DTM_FALSE);
|
|
}
|
|
}
|
|
|
|
void
|
|
OpenInboxCmd::undoit()
|
|
{
|
|
}
|
|
|
|
//
|
|
// OpenContainerCmd methods implementation.
|
|
// For the most part, we treat container->open() as a benign thing.
|
|
// The magic, as we see it, deals with converting the container
|
|
// if necessary.
|
|
// For OpenContainerCmd, if no conversion is necessary bingo! it opens.
|
|
// If conversion is necessary, it punts the work to ConvertContainerCmd.
|
|
//
|
|
//
|
|
|
|
OpenContainerCmd::OpenContainerCmd (
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : RoamInterruptibleCmd (name, label, active)
|
|
{
|
|
_menuWindow = window;
|
|
_open_create_flag = DTM_FALSE;
|
|
_open_lock_flag = DTM_FALSE;
|
|
}
|
|
|
|
// Parent's execute() ends up calling derived class's doit()
|
|
void
|
|
OpenContainerCmd::execute()
|
|
{
|
|
RoamInterruptibleCmd::execute();
|
|
}
|
|
|
|
void
|
|
OpenContainerCmd::execute(
|
|
RoamTaskDoneCallback rtd_callback,
|
|
void *clientData
|
|
)
|
|
{
|
|
RoamInterruptibleCmd::execute(rtd_callback, clientData);
|
|
}
|
|
|
|
// Tell the RMW to open. The RMW may end up calling its convert()
|
|
// which depends on ConvertContainerCmd's doit...
|
|
// By the time RMW->open() returns, the conversion would have
|
|
// been done too.
|
|
// This is the case of a RinterruptibleCmd derived class
|
|
// getting its work done in its doit() in one call.
|
|
//
|
|
|
|
void
|
|
OpenContainerCmd::doit()
|
|
{
|
|
DtMailEnv error;
|
|
|
|
assert(_menuWindow != NULL);
|
|
|
|
// Initialize the mail_error.
|
|
error.clear();
|
|
|
|
_menuWindow->open(error, _open_create_flag, _open_lock_flag);
|
|
if (error.isSet()) {
|
|
// Post a dialog indicating error and exit?
|
|
return; // for now. Should exit instead?
|
|
}
|
|
_done = TRUE;
|
|
}
|
|
|
|
void
|
|
OpenContainerCmd::undoit()
|
|
{
|
|
// Just print a message that allows us to trace the execution
|
|
|
|
DebugPrintf(1, "%s: undoit\n", name());
|
|
}
|
|
|
|
void
|
|
OpenContainerCmd::check_if_done()
|
|
{
|
|
// Have nothing fancy to do here. Since we do not want a dialog
|
|
// in any case, set it to true...
|
|
|
|
_done = TRUE;
|
|
|
|
}
|
|
|
|
|
|
void
|
|
OpenContainerCmd::post_dialog()
|
|
{
|
|
// Empty. We don't want a dialog on open...
|
|
}
|
|
|
|
void
|
|
OpenContainerCmd::unpost_dialog()
|
|
{
|
|
// Empty. We don't post, and we don't unpost.
|
|
}
|
|
void
|
|
OpenContainerCmd::updateMessage (char *msg)
|
|
{
|
|
RoamInterruptibleCmd::updateMessage(msg);
|
|
}
|
|
|
|
void
|
|
OpenContainerCmd::set_create_lock_flags(
|
|
DtMailBoolean create,
|
|
DtMailBoolean lock
|
|
)
|
|
{
|
|
_open_create_flag = create;
|
|
_open_lock_flag = lock;
|
|
}
|
|
|
|
|
|
// ConvertContainerCmd
|
|
// Here be dragons!
|
|
|
|
ConvertContainerCmd::ConvertContainerCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : RoamInterruptibleCmd (name, label, active)
|
|
{
|
|
_menuWindow = window;
|
|
_num_converted = 0;
|
|
_num_to_be_converted = 0;
|
|
_dialog = NULL;
|
|
_criteria = NULL;
|
|
_conv_cb = NULL;
|
|
_src = NULL;
|
|
_dest = NULL;
|
|
}
|
|
|
|
void
|
|
ConvertContainerCmd::execute()
|
|
{
|
|
if (!_dialog) {
|
|
_dialog = new DtMailWDM("Convert");
|
|
}
|
|
|
|
RoamInterruptibleCmd::execute();
|
|
}
|
|
|
|
void
|
|
ConvertContainerCmd::execute ( RoamTaskDoneCallback rtd_callback,
|
|
void *clientData)
|
|
{
|
|
if (!_dialog) {
|
|
_dialog = new DtMailWDM("Convert");
|
|
}
|
|
|
|
RoamInterruptibleCmd::execute(rtd_callback, clientData);
|
|
}
|
|
|
|
// Here be bigger dragons!
|
|
// The doit() calls the session->convert().
|
|
// And returns right away!
|
|
// the ses->convert() however ends up calling the conv_cb for every
|
|
// message that it has converted.
|
|
// So, we now have two loops working in parallel:
|
|
// 1) the parent()'s execute() class which called this doit() and is now
|
|
// calling check_if_done() periodically via its workProc;
|
|
// 2) the session->convert() which is calling the _conv_cb() for every
|
|
// message that it converts. In the _conv_cb(), we do the following:
|
|
// a) force update the dialog and see if it was interrupted;
|
|
// b) if not interrupted, set_convert_data() where we set _done if
|
|
// we are really done.
|
|
//
|
|
|
|
void
|
|
ConvertContainerCmd::doit()
|
|
{
|
|
assert(_menuWindow != NULL);
|
|
|
|
MailSession *ses = theRoamApp.session();
|
|
DtMailEnv mail_error;
|
|
|
|
// Initialize the mail_error.
|
|
mail_error.clear();
|
|
|
|
// ses->convert(mail_error, _src, _dest, _conv_cb, _menuWindow);
|
|
|
|
if (mail_error.isSet()) {
|
|
_menuWindow->postErrorDialog(mail_error);
|
|
}
|
|
}
|
|
|
|
void
|
|
ConvertContainerCmd::set_convert_data(
|
|
int converted,
|
|
int to_be_converted
|
|
)
|
|
{
|
|
_num_converted = converted;
|
|
_num_to_be_converted = to_be_converted;
|
|
|
|
if ((_num_converted == _num_to_be_converted) && !_interrupted) {
|
|
_done = TRUE;
|
|
}
|
|
}
|
|
|
|
int
|
|
ConvertContainerCmd::get_num_converted()
|
|
{
|
|
return(_num_converted);
|
|
}
|
|
|
|
|
|
void
|
|
ConvertContainerCmd::check_if_done()
|
|
{
|
|
if (_interrupted) {
|
|
_done = FALSE;
|
|
}
|
|
else if (_num_converted == _num_to_be_converted) {
|
|
_done = TRUE;
|
|
}
|
|
}
|
|
|
|
void
|
|
ConvertContainerCmd::updateDialog(
|
|
char *msg
|
|
)
|
|
{
|
|
forceUpdate(_dialog->baseWidget());
|
|
_dialog->updateDialog( msg );
|
|
}
|
|
|
|
void
|
|
ConvertContainerCmd::updateAnimation()
|
|
{
|
|
forceUpdate(_dialog->baseWidget());
|
|
_dialog->updateAnimation();
|
|
}
|
|
|
|
void
|
|
ConvertContainerCmd::post_dialog()
|
|
{
|
|
Dimension x, y, wid, ht;
|
|
|
|
char * buf = new char[25];
|
|
|
|
sprintf(buf, "Converted: %3d%%", 0);
|
|
|
|
_dialog->post ("Mailer",
|
|
buf,
|
|
_menuWindow->baseWidget(),
|
|
(void *) this,
|
|
NULL,
|
|
&RoamInterruptibleCmd::interruptCallback );
|
|
|
|
XtVaGetValues(_dialog->baseWidget(),
|
|
XmNx, &x,
|
|
XmNy, &y,
|
|
XmNwidth, &wid,
|
|
XmNheight, &ht,
|
|
NULL);
|
|
|
|
}
|
|
|
|
void
|
|
ConvertContainerCmd::unpost_dialog()
|
|
{
|
|
_dialog->unpost();
|
|
}
|
|
|
|
void
|
|
ConvertContainerCmd::undoit()
|
|
{
|
|
// Just print a message that allows us to trace the execution
|
|
|
|
DebugPrintf(1, "%s: undoit\n", name());
|
|
}
|
|
|
|
void
|
|
ConvertContainerCmd::set_data(
|
|
char *path1,
|
|
char *path2,
|
|
ConversionStatusCB cb
|
|
)
|
|
{
|
|
_src = path1;
|
|
_dest = path2;
|
|
_conv_cb = cb;
|
|
}
|
|
|
|
char *
|
|
ConvertContainerCmd::get_destination_name()
|
|
{
|
|
return _dest;
|
|
}
|
|
|
|
// Here be sheep!
|
|
// FindCmd
|
|
|
|
FindCmd::FindCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : RoamCmd ( name, label, active, window )
|
|
{
|
|
}
|
|
|
|
void
|
|
FindCmd::doit()
|
|
{
|
|
|
|
_menuwindow->get_find_dialog();
|
|
|
|
// SearchCmd::doit();
|
|
|
|
}
|
|
|
|
|
|
ChooseCmd::ChooseCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : NoUndoCmd( name, label, active )
|
|
{
|
|
_menuwindow = window;
|
|
_msgno = NULL;
|
|
}
|
|
|
|
void
|
|
ChooseCmd::doit()
|
|
{
|
|
|
|
}
|
|
|
|
SelectAllCmd::SelectAllCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : Cmd ( name, label, active )
|
|
{
|
|
_menuwindow = window;
|
|
}
|
|
|
|
void
|
|
SelectAllCmd::doit()
|
|
{
|
|
DtMailEnv mail_error;
|
|
|
|
_menuwindow->list()->select_all_and_display_last(mail_error);
|
|
}
|
|
|
|
void
|
|
SelectAllCmd::undoit()
|
|
{
|
|
}
|
|
|
|
|
|
DeleteCmd::DeleteCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : Cmd ( name, label, active )
|
|
{
|
|
_menuwindow = window;
|
|
_msgno = NULL;
|
|
}
|
|
|
|
void
|
|
DeleteCmd::doit()
|
|
{
|
|
_menuwindow->list()->deleteSelected(FALSE);
|
|
|
|
}
|
|
|
|
void
|
|
DeleteCmd::undoit()
|
|
{
|
|
|
|
}
|
|
|
|
DestroyCmd::DestroyCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : Cmd(name, label, active)
|
|
{
|
|
_menuwindow = window;
|
|
}
|
|
|
|
void
|
|
DestroyCmd::doit()
|
|
{
|
|
// Call Expunge only if there are deleted messages.
|
|
|
|
if (_menuwindow->list()->get_num_deleted_messages()) {
|
|
_menuwindow->expunge();
|
|
}
|
|
}
|
|
|
|
void
|
|
DestroyCmd::undoit()
|
|
{
|
|
}
|
|
|
|
// Unified Select File Cmd stuff
|
|
int UnifiedSelectFileCmd::_is_initialized = 0;
|
|
char *UnifiedSelectFileCmd::_unified_directory = NULL;
|
|
char *UnifiedSelectFileCmd::_unified_file = NULL;
|
|
int UnifiedSelectFileCmd::_unified_hidden = 0;
|
|
int UnifiedSelectFileCmd::_unify_selection = 1;
|
|
|
|
UnifiedSelectFileCmd::UnifiedSelectFileCmd (
|
|
char *name,
|
|
char *label,
|
|
char *title,
|
|
char *ok_label,
|
|
int active,
|
|
FileCallback
|
|
select_callback,
|
|
void *client_data,
|
|
Widget parent)
|
|
:SelectFileCmd (name,
|
|
label,
|
|
title,
|
|
ok_label,
|
|
active,
|
|
unifiedFileSelectedCB,
|
|
this,
|
|
unifiedFileCanceledCB,
|
|
this,
|
|
parent)
|
|
{
|
|
if (! _is_initialized)
|
|
{
|
|
FORCE_SEGV_DECL(DtMail::Session, m_session);
|
|
DtMailEnv error;
|
|
const char *dirname = NULL;
|
|
const char *expanded_dirname = NULL;
|
|
const char *value = NULL;
|
|
char *full_dirname = NULL;
|
|
|
|
_unified_directory = NULL;
|
|
_unified_file = NULL;
|
|
_unified_hidden = 0;
|
|
_unify_selection = 1;
|
|
_is_initialized = 1;
|
|
|
|
m_session = theRoamApp.session()->session();
|
|
|
|
error.clear();
|
|
m_session->mailRc(error)->getValue(error, "filefolder", &dirname);
|
|
if (error.isSet()) {
|
|
dirname = strdup("~");
|
|
error.clear();
|
|
}
|
|
expanded_dirname = m_session->expandPath(error, dirname);
|
|
_unified_directory = XtNewString(expanded_dirname);
|
|
|
|
error.clear();
|
|
m_session->mailRc(error)->getValue(
|
|
error,
|
|
"dontunifyfileselection",
|
|
&value);
|
|
if (! error.isSet())
|
|
_unify_selection = 0;
|
|
|
|
free((void*) dirname);
|
|
free((void*) expanded_dirname);
|
|
free((void*) value);
|
|
}
|
|
|
|
_select_file_callback = select_callback;
|
|
_select_file_client_data = client_data;
|
|
_genDialog = new DtMailGenDialog("Dialog", parent);
|
|
}
|
|
|
|
UnifiedSelectFileCmd::~UnifiedSelectFileCmd()
|
|
{
|
|
if (_genDialog) delete _genDialog;
|
|
}
|
|
|
|
void
|
|
UnifiedSelectFileCmd::doit()
|
|
{
|
|
if (NULL == _fileBrowser)
|
|
{
|
|
SelectFileCmd::doit();
|
|
if (NULL != _unified_directory)
|
|
setDirectory(_unified_directory);
|
|
if (NULL != _unified_file)
|
|
setSelected(_unified_file);
|
|
setHidden(_unified_hidden);
|
|
}
|
|
else
|
|
{
|
|
if (_unify_selection)
|
|
{
|
|
if (NULL != _unified_directory)
|
|
setDirectory(_unified_directory);
|
|
if (NULL != _unified_file)
|
|
setSelected(_unified_file);
|
|
setHidden(_unified_hidden);
|
|
}
|
|
SelectFileCmd::doit();
|
|
}
|
|
}
|
|
|
|
void
|
|
UnifiedSelectFileCmd::unifiedFileSelectedCB(void *client_data, char *selection)
|
|
{
|
|
UnifiedSelectFileCmd *self = (UnifiedSelectFileCmd *) client_data;
|
|
|
|
if (NULL != self)
|
|
{
|
|
self->updateUnifiedData();
|
|
self->unifiedFileSelected(selection);
|
|
}
|
|
}
|
|
|
|
void
|
|
UnifiedSelectFileCmd::unifiedFileSelected(char *selection)
|
|
{
|
|
DtMailEnv error;
|
|
|
|
SafePathIsAccessible(error, selection);
|
|
if (error.isSet())
|
|
{
|
|
const char *errmsg = NULL;
|
|
char *err;
|
|
int answer;
|
|
|
|
errmsg = (const char*) error;
|
|
err = strdup(errmsg);
|
|
|
|
_genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 48, "Mailer"), err);
|
|
answer = _genDialog->post_and_return(DTMAILHELPERROR);
|
|
if (1 == answer) doit();
|
|
if (err) free(err);
|
|
return;
|
|
}
|
|
|
|
if (_select_file_callback)
|
|
_select_file_callback(_select_file_client_data, selection);
|
|
}
|
|
|
|
void
|
|
UnifiedSelectFileCmd::unifiedFileCanceledCB(void *client_data, char *)
|
|
{
|
|
UnifiedSelectFileCmd *self = (UnifiedSelectFileCmd *) client_data;
|
|
|
|
if (NULL != self)
|
|
self->updateUnifiedData();
|
|
}
|
|
|
|
void
|
|
UnifiedSelectFileCmd::updateUnifiedData()
|
|
{
|
|
if (! _unify_selection)
|
|
return;
|
|
|
|
if (NULL != _unified_file)
|
|
XtFree(_unified_file);
|
|
_unified_file = getSelected();
|
|
|
|
|
|
if (NULL != _unified_directory)
|
|
XtFree(_unified_directory);
|
|
_unified_directory = getDirectory();
|
|
|
|
_unified_hidden = getHidden();
|
|
}
|
|
|
|
// Unified Select Mailbox Cmd stuff
|
|
int UnifiedSelectMailboxCmd::_is_initialized = 0;
|
|
char *UnifiedSelectMailboxCmd::_unified_directory = NULL;
|
|
char *UnifiedSelectMailboxCmd::_unified_file = NULL;
|
|
int UnifiedSelectMailboxCmd::_unified_hidden = 0;
|
|
int UnifiedSelectMailboxCmd::_unify_selection = 1;
|
|
|
|
UnifiedSelectMailboxCmd::UnifiedSelectMailboxCmd (
|
|
char *name,
|
|
char *label,
|
|
char *title,
|
|
char *ok_label,
|
|
int active,
|
|
FileCallback
|
|
select_callback,
|
|
void *client_data,
|
|
Widget parent,
|
|
DtMailBoolean only_show_mailboxes)
|
|
:SelectFileCmd (name,
|
|
label,
|
|
title,
|
|
ok_label,
|
|
active,
|
|
unifiedMailboxSelectedCB,
|
|
this,
|
|
unifiedMailboxCanceledCB,
|
|
this,
|
|
parent)
|
|
{
|
|
_only_show_mailboxes = DTM_FALSE;
|
|
|
|
if (! _is_initialized)
|
|
{
|
|
FORCE_SEGV_DECL(DtMail::Session, m_session);
|
|
DtMailEnv error;
|
|
const char *dirname = NULL;
|
|
const char *expanded_dirname = NULL;
|
|
const char *value = NULL;
|
|
char *full_dirname = NULL;
|
|
|
|
_unified_directory = NULL;
|
|
_unified_file = NULL;
|
|
_unified_hidden = 0;
|
|
_unify_selection = 1;
|
|
_is_initialized = 1;
|
|
_only_show_mailboxes = only_show_mailboxes;
|
|
|
|
m_session = theRoamApp.session()->session();
|
|
|
|
error.clear();
|
|
m_session->mailRc(error)->getValue(error, "folder", &dirname);
|
|
if (error.isSet()) {
|
|
dirname = strdup("~");
|
|
error.clear();
|
|
}
|
|
expanded_dirname = m_session->expandPath(error, dirname);
|
|
_unified_directory = XtNewString(expanded_dirname);
|
|
|
|
error.clear();
|
|
m_session->mailRc(error)->getValue(
|
|
error,
|
|
"dontunifyfileselection",
|
|
&value);
|
|
if (! error.isSet())
|
|
_unify_selection = 0;
|
|
|
|
free((void*) dirname);
|
|
free((void*) expanded_dirname);
|
|
free((void*) value);
|
|
}
|
|
|
|
_select_file_callback = select_callback;
|
|
_select_file_client_data = client_data;
|
|
_genDialog = new DtMailGenDialog("Dialog", parent);
|
|
}
|
|
|
|
UnifiedSelectMailboxCmd::~UnifiedSelectMailboxCmd()
|
|
{
|
|
if (_genDialog) delete _genDialog;
|
|
}
|
|
|
|
void
|
|
UnifiedSelectMailboxCmd::doit()
|
|
{
|
|
if (NULL == _fileBrowser)
|
|
{
|
|
SelectFileCmd::doit();
|
|
if (NULL != _unified_directory)
|
|
setDirectory(_unified_directory);
|
|
if (NULL != _unified_file)
|
|
setSelected(_unified_file);
|
|
setHidden(_unified_hidden);
|
|
|
|
if (_fileBrowser)
|
|
XtVaSetValues(
|
|
_fileBrowser,
|
|
XmNfileSearchProc,
|
|
UnifiedSelectMailboxCmd::unifiedMailboxSearchProc,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
if (_unify_selection)
|
|
{
|
|
if (NULL != _unified_directory)
|
|
setDirectory(_unified_directory);
|
|
if (NULL != _unified_file)
|
|
setSelected(_unified_file);
|
|
setHidden(_unified_hidden);
|
|
}
|
|
SelectFileCmd::doit();
|
|
}
|
|
}
|
|
|
|
extern "C" {
|
|
extern void _XmOSBuildFileList(
|
|
String dirPath,
|
|
String pattern,
|
|
#if NeedWidePrototypes
|
|
unsigned int typeMask,
|
|
#else
|
|
unsigned char typeMask,
|
|
#endif /* NeedWidePrototypes */
|
|
String **pEntries,
|
|
unsigned int *pNumEntries,
|
|
unsigned int *pNumAlloc);
|
|
|
|
extern int _XmOSFileCompare(const void *sp1, const void *sp2);
|
|
extern char *_XmStringGetTextConcat(XmString string);
|
|
}
|
|
|
|
void
|
|
UnifiedSelectMailboxCmd::unifiedMailboxSearchProc(
|
|
Widget w,
|
|
XtPointer sd)
|
|
{
|
|
XmFileSelectionBoxWidget fs =
|
|
(XmFileSelectionBoxWidget) w;
|
|
XmFileSelectionBoxCallbackStruct * searchData =
|
|
(XmFileSelectionBoxCallbackStruct *) sd;
|
|
String dir;
|
|
String pattern;
|
|
Arg args[3];
|
|
int Index;
|
|
String * fileList;
|
|
unsigned int numFiles;
|
|
unsigned int numItems = 0;
|
|
unsigned int numAlloc;
|
|
XmString * XmStringFileList;
|
|
unsigned dirLen;
|
|
XtEnum fileFilterStyle, pathMode;
|
|
unsigned char fileTypeMask;
|
|
|
|
if (!(dir = _XmStringGetTextConcat(searchData->dir)))
|
|
return ;
|
|
|
|
if (!(pattern = _XmStringGetTextConcat(searchData->pattern)))
|
|
{
|
|
XtFree(dir);
|
|
return;
|
|
}
|
|
fileList = NULL;
|
|
|
|
XtVaGetValues(
|
|
w,
|
|
XmNfileTypeMask, &fileTypeMask,
|
|
XmNfileFilterStyle, &fileFilterStyle,
|
|
XmNpathMode, &pathMode,
|
|
NULL);
|
|
|
|
_XmOSBuildFileList(
|
|
dir, pattern, fileTypeMask,
|
|
&fileList, &numFiles, &numAlloc);
|
|
|
|
if (fileList && numFiles)
|
|
{
|
|
Boolean showDotFiles = (fileFilterStyle == XmFILTER_NONE);
|
|
|
|
if (numFiles > 1)
|
|
qsort((void*) fileList, numFiles, sizeof(char*), _XmOSFileCompare);
|
|
|
|
XmStringFileList = (XmString*) XtMalloc(numFiles*sizeof(XmString));
|
|
|
|
Index = 0;
|
|
dirLen = strlen(dir);
|
|
|
|
while (Index < numFiles)
|
|
{
|
|
Boolean isMailBox = 0;
|
|
char *dataType = NULL;
|
|
|
|
dataType = DtDtsFileToDataType(fileList[Index]);
|
|
if (dataType)
|
|
isMailBox = (0 == strcmp(dataType, "DTMAIL_FILE"));
|
|
DtDtsFreeDataType(dataType);
|
|
|
|
if (isMailBox &&
|
|
(showDotFiles || ((fileList[Index])[dirLen] != '.')) )
|
|
{
|
|
if (pathMode == XmPATH_MODE_FULL)
|
|
XmStringFileList[numItems++] =
|
|
XmStringGenerate(fileList[Index],
|
|
XmFONTLIST_DEFAULT_TAG,
|
|
XmCHARSET_TEXT, NULL);
|
|
else
|
|
XmStringFileList[numItems++] =
|
|
XmStringGenerate(&(fileList[Index])[dirLen],
|
|
XmFONTLIST_DEFAULT_TAG,
|
|
XmCHARSET_TEXT, NULL) ;
|
|
}
|
|
++Index ;
|
|
}
|
|
|
|
/* Update the list.
|
|
*/
|
|
Index = 0 ;
|
|
XtVaSetValues(
|
|
w,
|
|
XmNfileListItemCount, numItems,
|
|
XmNfileListItems, XmStringFileList,
|
|
XmNlistUpdated, TRUE,
|
|
NULL);
|
|
|
|
Index = numFiles;
|
|
while(Index--)
|
|
XtFree( fileList[Index]);
|
|
|
|
while(numItems--)
|
|
XmStringFree(XmStringFileList[numItems]);
|
|
|
|
XtFree((char*) XmStringFileList);
|
|
}
|
|
else
|
|
{
|
|
XtVaSetValues(
|
|
w,
|
|
XmNfileListItemCount, 0,
|
|
XmNfileListItems, NULL,
|
|
XmNlistUpdated, TRUE,
|
|
NULL);
|
|
}
|
|
|
|
XtFree((char *) fileList);
|
|
XtFree(pattern);
|
|
XtFree(dir);
|
|
return;
|
|
}
|
|
|
|
void
|
|
UnifiedSelectMailboxCmd::unifiedMailboxSelectedCB(
|
|
void *client_data,
|
|
char *selection)
|
|
{
|
|
UnifiedSelectMailboxCmd *self = (UnifiedSelectMailboxCmd *) client_data;
|
|
|
|
if (NULL != self)
|
|
{
|
|
self->updateUnifiedData();
|
|
self->unifiedMailboxSelected(
|
|
self->_select_file_callback,
|
|
self->_select_file_client_data,
|
|
selection);
|
|
}
|
|
}
|
|
|
|
void
|
|
UnifiedSelectMailboxCmd::unifiedMailboxSelected(
|
|
FileCallback cb,
|
|
void *client_data,
|
|
char *selection)
|
|
{
|
|
DtMailEnv error;
|
|
|
|
SafePathIsAccessible(error, selection);
|
|
if (error.isSet())
|
|
{
|
|
const char *errmsg = NULL;
|
|
char *err = NULL;
|
|
int answer;
|
|
|
|
errmsg = (const char*) error;
|
|
err = strdup(errmsg);
|
|
|
|
_genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 48, "Mailer"), err);
|
|
answer = _genDialog->post_and_return(DTMAILHELPERROR);
|
|
if (1 == answer) doit();
|
|
if (err) free(err);
|
|
return;
|
|
}
|
|
|
|
updateUnifiedData();
|
|
if (cb) cb(client_data, selection);
|
|
}
|
|
|
|
void
|
|
UnifiedSelectMailboxCmd::unifiedMailboxCanceledCB(void *client_data, char *)
|
|
{
|
|
UnifiedSelectMailboxCmd *self = (UnifiedSelectMailboxCmd *) client_data;
|
|
|
|
if (NULL != self)
|
|
self->updateUnifiedData();
|
|
}
|
|
|
|
void
|
|
UnifiedSelectMailboxCmd::updateUnifiedData()
|
|
{
|
|
if (! _unify_selection)
|
|
return;
|
|
|
|
if (NULL != _unified_file)
|
|
XtFree(_unified_file);
|
|
_unified_file = getSelected();
|
|
|
|
|
|
if (NULL != _unified_directory)
|
|
XtFree(_unified_directory);
|
|
_unified_directory = getDirectory();
|
|
|
|
_unified_hidden = getHidden();
|
|
}
|
|
|
|
ContainerMenuCmd::ContainerMenuCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window,
|
|
ContainerOp op
|
|
) : RoamCmd ( name, label, active, window )
|
|
{
|
|
_menuwindow = window;
|
|
_container_name = name;
|
|
_operation = op;
|
|
}
|
|
|
|
void
|
|
ContainerMenuCmd::doit()
|
|
{
|
|
DtMailEnv mail_error;
|
|
|
|
// Initialize mail_error.
|
|
mail_error.clear();
|
|
|
|
theRoamApp.busyAllWindows(GETMSG(DT_catd, 3, 15, "Saving..."));
|
|
_menuwindow->mailbox()->save();
|
|
theRoamApp.unbusyAllWindows();
|
|
|
|
switch (_operation)
|
|
{
|
|
case DTM_NONE:
|
|
break;
|
|
case DTM_OPEN:
|
|
_menuwindow->view_mail_file(_container_name, DTM_FALSE);
|
|
break;
|
|
case DTM_COPY:
|
|
_menuwindow->list()->copySelected(
|
|
mail_error,
|
|
_container_name,
|
|
FALSE, FALSE);
|
|
if (mail_error.isSet())
|
|
{
|
|
// We had an error in copying the message to a container!
|
|
}
|
|
break;
|
|
case DTM_MOVE:
|
|
_menuwindow->list()->copySelected(
|
|
mail_error,
|
|
_container_name,
|
|
TRUE, FALSE);
|
|
if (mail_error.isSet())
|
|
{
|
|
// We had an error in moving the message to a container!
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
ContainerMenuCmd::~ContainerMenuCmd()
|
|
{
|
|
}
|
|
|
|
|
|
// Move the messages that are selected in the RoamMenuWindow to the Inbox.
|
|
MoveToInboxCmd::MoveToInboxCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : RoamCmd (name, label, active, window)
|
|
{
|
|
_menuwindow = window;
|
|
}
|
|
|
|
void
|
|
MoveToInboxCmd::doit()
|
|
{
|
|
DtMailEnv mail_error;
|
|
|
|
// Initialize mail_error.
|
|
mail_error.clear();
|
|
|
|
// Get a handle to the Inbox.
|
|
char * mail_file = NULL;
|
|
DtMailObjectSpace space;
|
|
DtMail::Session * d_session = theRoamApp.session()->session();
|
|
|
|
d_session->queryImpl(mail_error,
|
|
d_session->getDefaultImpl(mail_error),
|
|
DtMailCapabilityInboxName,
|
|
&space,
|
|
&mail_file);
|
|
_menuwindow->list()->copySelected(mail_error, mail_file, TRUE, FALSE);
|
|
if (mail_error.isSet()) {
|
|
// We had an error in moving the messages to the Inbox!
|
|
}
|
|
}
|
|
|
|
MoveToInboxCmd::~MoveToInboxCmd()
|
|
{
|
|
}
|
|
|
|
// Copy the selected messages to the Inbox.
|
|
CopyToInboxCmd::CopyToInboxCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : RoamCmd (name, label, active, window)
|
|
{
|
|
_menuwindow = window;
|
|
}
|
|
|
|
void
|
|
CopyToInboxCmd::doit()
|
|
{
|
|
DtMailEnv mail_error;
|
|
|
|
// Initialize mail_error.
|
|
mail_error.clear();
|
|
|
|
// Get a handle to the Inbox.
|
|
char * mail_file = NULL;
|
|
DtMailObjectSpace space;
|
|
DtMail::Session * d_session = theRoamApp.session()->session();
|
|
|
|
d_session->queryImpl(mail_error,
|
|
d_session->getDefaultImpl(mail_error),
|
|
DtMailCapabilityInboxName,
|
|
&space,
|
|
&mail_file);
|
|
_menuwindow->list()->copySelected(mail_error, mail_file, FALSE, FALSE);
|
|
if (mail_error.isSet()) {
|
|
// We ad an error in copying the messages to the Inbox!
|
|
}
|
|
}
|
|
|
|
CopyToInboxCmd::~CopyToInboxCmd()
|
|
{
|
|
}
|
|
|
|
|
|
// This is hooked up the Undelete button in the Deleted
|
|
// Messages List dialog box.
|
|
|
|
DoUndeleteCmd::DoUndeleteCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
UndelFromListDialog *undelDialog
|
|
) : Cmd ( name, label, active )
|
|
{
|
|
_undelDialog = undelDialog;
|
|
}
|
|
|
|
void
|
|
DoUndeleteCmd::doit()
|
|
{
|
|
// Undelete the selected messages.
|
|
_undelDialog->undelSelected();
|
|
}
|
|
|
|
void
|
|
DoUndeleteCmd::undoit()
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
DoUndeleteCmd::~DoUndeleteCmd()
|
|
{
|
|
}
|
|
|
|
// This is hooked up to the Close button in the Deleted Messages
|
|
// List dialog box.
|
|
|
|
CloseUndelCmd::CloseUndelCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
UndelFromListDialog *undelDialog
|
|
) : Cmd ( name, label, active )
|
|
{
|
|
_undelDialog = undelDialog;
|
|
}
|
|
|
|
void
|
|
CloseUndelCmd::doit()
|
|
{
|
|
// Close the dialog.
|
|
_undelDialog->popped_down();
|
|
}
|
|
|
|
void
|
|
CloseUndelCmd::undoit()
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
|
|
CloseUndelCmd::~CloseUndelCmd()
|
|
{
|
|
}
|
|
|
|
UndeleteCmd::UndeleteCmd (
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window,
|
|
Boolean viaDeleteList
|
|
) : ChooseCmd ( name, label, active, window )
|
|
{
|
|
_menuwindow = window;
|
|
_undelFromList = NULL;
|
|
_fromList = viaDeleteList;
|
|
_clientData = NULL;
|
|
_num_deleted = 0;
|
|
}
|
|
|
|
UndeleteCmd::~UndeleteCmd()
|
|
{
|
|
}
|
|
|
|
void
|
|
UndeleteCmd::doit()
|
|
{
|
|
FORCE_SEGV_DECL(MsgStruct, tmpMS);
|
|
MsgScrollingList *list = _menuwindow->list();
|
|
MsgHndArray *deleted_messages;
|
|
DtMailEnv mail_error;
|
|
|
|
// Initialize the mail_error.
|
|
mail_error.clear();
|
|
|
|
|
|
if (_fromList) {
|
|
// Create the Deleted Messages Dialog
|
|
|
|
if (_undelFromList) {
|
|
// Hack for user testing. If the dialog is up, we destroy it.
|
|
XtDestroyWidget(_undelFromList->baseWidget());
|
|
}
|
|
// if (!_undelFromList) {
|
|
_undelFromList = new UndelFromListDialog(
|
|
GETMSG(DT_catd, 1, 227, "Mailer - Deleted Messages"),
|
|
_menuwindow);
|
|
_undelFromList->initialize();
|
|
|
|
// Check for existing list of deleted messages
|
|
_num_deleted = list->get_num_deleted_messages();
|
|
|
|
// If there are deleted messages, put them in the Deleted
|
|
// Messages List.
|
|
|
|
if (_num_deleted > 0) {
|
|
deleted_messages = list->get_deleted_messages();
|
|
_undelFromList->loadMsgs(
|
|
mail_error,
|
|
deleted_messages,
|
|
_num_deleted);
|
|
if (mail_error.isSet()) {
|
|
// Post an exception here!
|
|
_menuwindow->postErrorDialog(mail_error);
|
|
}
|
|
|
|
}
|
|
// Display the dialog
|
|
|
|
_undelFromList->popped_up();
|
|
} else {
|
|
// Although we don't display the Deleted Message Dialog here, we
|
|
// need to make sure that it gets updated for the next time
|
|
// we bring it up.
|
|
list->undelete_last_deleted();
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef DEAD_WOOD
|
|
SaveCmd::SaveCmd ( char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : RoamCmd ( name, label, active, window )
|
|
{
|
|
|
|
}
|
|
|
|
void
|
|
SaveCmd::doit()
|
|
{
|
|
|
|
assert(_menuwindow->mailbox() != NULL);
|
|
}
|
|
#endif /* DEAD_WOOD */
|
|
|
|
|
|
|
|
MoveCopyCmd::MoveCopyCmd( char *name,
|
|
char *label,
|
|
int active,
|
|
FileCallback move_callback,
|
|
FileCallback copy_callback,
|
|
RoamMenuWindow * menu_window,
|
|
Widget parent,
|
|
DtMailBoolean only_show_mailboxes)
|
|
: UnifiedSelectMailboxCmd(name,
|
|
label,
|
|
GETMSG(DT_catd, 1, 89, "Mailer - Other Mailboxes"),
|
|
"Move",
|
|
active,
|
|
move_callback,
|
|
menu_window,
|
|
parent,
|
|
only_show_mailboxes)
|
|
{
|
|
_copy_callback = copy_callback;
|
|
_menuwindow = menu_window;
|
|
_copy_button = NULL;
|
|
_move_button = NULL;
|
|
_file_list = NULL;
|
|
_file_text = NULL;
|
|
_default_button = NULL;
|
|
}
|
|
|
|
MoveCopyCmd::~MoveCopyCmd()
|
|
{
|
|
}
|
|
|
|
void
|
|
MoveCopyCmd::setDefault(Widget button)
|
|
{
|
|
Arg args[1];
|
|
|
|
_default_button = button;
|
|
XtSetArg( args[0], XmNdefaultButton, _default_button );
|
|
XtSetValues( _fileBrowser, args, 1 );
|
|
}
|
|
|
|
void
|
|
MoveCopyCmd::doit()
|
|
{
|
|
XmString move;
|
|
Widget filter_button;
|
|
Widget unused_button;
|
|
Widget action_area;
|
|
DtMailEnv error;
|
|
|
|
if (!_fileBrowser) {
|
|
UnifiedSelectMailboxCmd::doit();
|
|
// Customize buttons for MoveCopy dialog
|
|
move = XmStringCreateLocalized(GETMSG(DT_catd, 1, 90, "Move"));
|
|
|
|
filter_button = XtNameToWidget(_fileBrowser, "*Apply");
|
|
_move_button = XtNameToWidget(_fileBrowser, "*OK");
|
|
action_area = XtParent(_move_button);
|
|
unused_button = XtVaCreateWidget(
|
|
"Unused Button",
|
|
xmPushButtonWidgetClass, _fileBrowser,
|
|
NULL);
|
|
_copy_button = XtVaCreateManagedWidget(
|
|
GETMSG(DT_catd, 1, 237, "Copy"),
|
|
/*xmPushButtonWidgetClass, _fileBrowser,*/
|
|
xmPushButtonGadgetClass, _fileBrowser,
|
|
XmNlabelString,
|
|
XmStringCreateLocalized(GETMSG(DT_catd, 1, 43, "Copy")),
|
|
NULL);
|
|
printHelpId("Copy", _copy_button);
|
|
//
|
|
// add help callback
|
|
// XtAddCallback(_copy_button, XmNhelpCallback, HelpCB, helpId);
|
|
//
|
|
XtAddCallback(
|
|
_copy_button,
|
|
XmNhelpCallback,
|
|
HelpCB,
|
|
(void *)"dtmailViewmainWindowWork-AreapanedWform2RowColumnMoveCopy");
|
|
XtAddCallback(
|
|
_copy_button,
|
|
XmNactivateCallback,
|
|
&MoveCopyCmd::fileSelectedCallback2,
|
|
(XtPointer) this );
|
|
|
|
if (_menuwindow->mailbox()->mailBoxWritable(error) == DTM_FALSE)
|
|
XtUnmanageChild(_move_button);
|
|
else
|
|
XtManageChild(_move_button);
|
|
|
|
// XtVaSetValues(_move_button, XmNsensitive, FALSE);
|
|
|
|
_file_list = XtNameToWidget(_fileBrowser, "*ItemsList");
|
|
XtAddCallback(
|
|
_file_list,
|
|
XmNbrowseSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
|
|
(XtPointer) this);
|
|
XtAddCallback(
|
|
_file_list,
|
|
XmNextendedSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
|
|
(XtPointer) this);
|
|
XtAddCallback(
|
|
_file_list,
|
|
XmNmultipleSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
|
|
(XtPointer) this);
|
|
XtAddCallback(
|
|
_file_list,
|
|
XmNsingleSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
|
|
(XtPointer) this);
|
|
|
|
_file_text = XtNameToWidget(_fileBrowser, "*Text");
|
|
if (NULL != _file_text)
|
|
XtAddCallback(
|
|
_file_text,
|
|
XmNfocusCallback, &MoveCopyCmd::setDefaultButtonCB,
|
|
(XtPointer) this);
|
|
|
|
XmStringFree(move);
|
|
|
|
} else {
|
|
UnifiedSelectMailboxCmd::doit();
|
|
}
|
|
|
|
}
|
|
|
|
void
|
|
MoveCopyCmd::fileSelectedCallback2 (
|
|
Widget ,
|
|
XtPointer clientData,
|
|
XtPointer callData
|
|
)
|
|
{
|
|
MoveCopyCmd *obj = (MoveCopyCmd *) clientData;
|
|
XmFileSelectionBoxCallbackStruct *cb =
|
|
(XmFileSelectionBoxCallbackStruct *) callData;
|
|
char *name = NULL;
|
|
char *dir_str = NULL;
|
|
char *fname = NULL;
|
|
char *dname = NULL;
|
|
int status = 0;
|
|
XmString xmstr;
|
|
|
|
static char selected[MAXPATHLEN+1];
|
|
|
|
// Bring the file selection dialog down.
|
|
XtUnmanageChild ( obj->_fileBrowser );
|
|
|
|
//
|
|
// Get the file name
|
|
//
|
|
XtVaGetValues(obj->_fileBrowser, XmNdirectory, &xmstr, NULL);
|
|
if (xmstr)
|
|
dname = (char*) _XmStringUngenerate(
|
|
xmstr, NULL,
|
|
XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
|
|
|
|
//
|
|
// Get the file name
|
|
//
|
|
XtVaGetValues(obj->_fileBrowser, XmNdirSpec, &xmstr, NULL);
|
|
if (xmstr)
|
|
{
|
|
// Extract the first character string matching the default
|
|
// character set from the compound string
|
|
fname = (char *) _XmStringUngenerate(
|
|
xmstr, NULL,
|
|
XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
|
|
|
|
if (NULL == fname || strlen(fname) == 0)
|
|
return;
|
|
|
|
// If a string was successfully extracted, call
|
|
// unifiedMailboxSelected to handle the file.
|
|
*selected = '\0';
|
|
if (NULL != dname) snprintf(selected, sizeof(selected), "%s", dname);
|
|
strcat(selected, fname);
|
|
obj->updateUnifiedData();
|
|
obj->unifiedMailboxSelected(
|
|
obj->_copy_callback,
|
|
obj->_menuwindow,
|
|
selected);
|
|
}
|
|
}
|
|
|
|
void
|
|
MoveCopyCmd::setDefaultButtonCB(
|
|
Widget,
|
|
XtPointer clientData,
|
|
XtPointer)
|
|
{
|
|
MoveCopyCmd *thisCmd = (MoveCopyCmd *) clientData;
|
|
thisCmd->setDefault(thisCmd->_default_button);
|
|
}
|
|
|
|
|
|
CopyCmd::CopyCmd( char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window,
|
|
MoveCopyCmd *move_copy_cmd
|
|
) : RoamCmd ( name, label, active, window )
|
|
{
|
|
_move_copy_cmd = move_copy_cmd;
|
|
}
|
|
|
|
CopyCmd::~CopyCmd()
|
|
{
|
|
}
|
|
|
|
void
|
|
CopyCmd::doit()
|
|
{
|
|
_move_copy_cmd->doit();
|
|
_move_copy_cmd->setDefault(_move_copy_cmd->getCopyButton());
|
|
}
|
|
|
|
|
|
MoveCmd::MoveCmd( char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window,
|
|
MoveCopyCmd *move_copy_cmd
|
|
) : RoamCmd ( name, label, active, window )
|
|
{
|
|
_move_copy_cmd = move_copy_cmd;
|
|
}
|
|
|
|
MoveCmd::~MoveCmd()
|
|
{
|
|
}
|
|
|
|
void
|
|
MoveCmd::doit()
|
|
{
|
|
_move_copy_cmd->doit();
|
|
_move_copy_cmd->setDefault(_move_copy_cmd->getMoveButton());
|
|
}
|
|
|
|
|
|
NextCmd::NextCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : RoamCmd ( name, label, active, window )
|
|
{
|
|
}
|
|
|
|
void
|
|
NextCmd::doit()
|
|
{
|
|
_menuwindow->list()->select_next_item();
|
|
}
|
|
|
|
|
|
PrevCmd::PrevCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : RoamCmd ( name, label, active, window )
|
|
{
|
|
}
|
|
|
|
void
|
|
PrevCmd::doit()
|
|
{
|
|
_menuwindow->list()->select_prev_item();
|
|
}
|
|
|
|
#ifdef DEAD_WOOD
|
|
MessagesCmd::MessagesCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : RoamCmd ( name, label, active, window )
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
MessagesCmd::doit()
|
|
{
|
|
Boolean old=_menuwindow->fullHeader();
|
|
MsgScrollingList *list=_menuwindow->list();
|
|
|
|
( !strcmp( this->name(), "Full Header" ) ? _menuwindow->fullHeader( True ) : _menuwindow->fullHeader( False ) );
|
|
|
|
if ( old!=_menuwindow->fullHeader() && _menuwindow->msgView() ) {
|
|
// list->chooseCurrent();
|
|
}
|
|
|
|
}
|
|
#endif /* DEAD_WOOD */
|
|
|
|
PrintCmd::PrintCmd (
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
int silent,
|
|
RoamMenuWindow *window
|
|
) : ChooseCmd ( name, label, active, window ), _tmp_files(5)
|
|
{
|
|
_parent = window;
|
|
_silent = silent;
|
|
}
|
|
|
|
void
|
|
PrintCmd::doit()
|
|
{
|
|
// The entire implementation of print was broken. It has
|
|
// be removed until a proper implementation can be provided.
|
|
// dlp 10/04/93
|
|
|
|
printit(_silent);
|
|
return;
|
|
}
|
|
|
|
void
|
|
PrintCmd::actioncb(
|
|
DtActionInvocationID id,
|
|
XtPointer clientData,
|
|
DtActionArg *,
|
|
int,
|
|
int status
|
|
)
|
|
{
|
|
PrintCmd *data;
|
|
|
|
switch (status) {
|
|
case DtACTION_INVOKED:
|
|
break;
|
|
default:
|
|
data = (PrintCmd *)clientData;
|
|
data->_parent->message("");
|
|
data->_unregister_tmp_file(id);
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void
|
|
PrintCmd::printjobcb( Widget w, XtPointer client_data, XtPointer )
|
|
{
|
|
char *filename = (char *) client_data;
|
|
|
|
XtRemoveCallback(w, XtNdestroyCallback, &PrintCmd::printjobcb, filename);
|
|
|
|
unlink(filename);
|
|
free(filename);
|
|
}
|
|
|
|
void
|
|
PrintCmd::printit( int silent )
|
|
{
|
|
char *p;
|
|
char *silent_str = "DTPRINTSILENT";
|
|
char *tmpdir = new char[MAXPATHLEN+1];
|
|
DtMailEnv mail_error;
|
|
MsgScrollingList *list;
|
|
|
|
DebugPrintf(1, "%s: printit\n", name());
|
|
|
|
// Create tmp file.
|
|
snprintf(tmpdir, MAXPATHLEN+1, "%s/%s", getenv("HOME"), DtPERSONAL_TMP_DIRECTORY);
|
|
if ((p = tempnam(tmpdir, "dtmail")) == NULL) {
|
|
delete [] tmpdir;
|
|
return;
|
|
}
|
|
delete [] tmpdir;
|
|
|
|
mail_error.clear();
|
|
list = _parent->list();
|
|
|
|
// Copy selected messages to a temp file
|
|
int status = list->copySelected(mail_error, p, FALSE, TRUE);
|
|
if (mail_error.isSet())
|
|
{
|
|
_parent->postErrorDialog(mail_error);
|
|
free(p);
|
|
return;
|
|
}
|
|
if (0 != status) return;
|
|
|
|
|
|
DmxPrintJob *pjob = new DmxPrintJob(p,
|
|
(silent ? DTM_TRUE : DTM_FALSE),
|
|
_parent);
|
|
|
|
XtAddCallback(pjob->baseWidget(),
|
|
XtNdestroyCallback,
|
|
&PrintCmd::printjobcb,
|
|
(XtPointer) strdup(p));
|
|
|
|
pjob->execute();
|
|
free(p);
|
|
return;
|
|
}
|
|
|
|
int
|
|
PrintCmd::_register_tmp_file(
|
|
const char *name,
|
|
DtActionInvocationID id
|
|
)
|
|
{
|
|
struct tmp_file *f;
|
|
|
|
// Allocate struct to hold id and temp file
|
|
if ((f = (struct tmp_file *)malloc(sizeof(struct tmp_file))) == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
// Save file name and action id
|
|
f->file = strdup(name);
|
|
f->id = id;
|
|
|
|
// Add to list of temp files
|
|
_tmp_files.append(f);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
PrintCmd::_unregister_tmp_file(
|
|
DtActionInvocationID id
|
|
)
|
|
{
|
|
int n;
|
|
struct tmp_file *f;
|
|
|
|
// Find the temp file that was used by the Action specified by id
|
|
for (n = _tmp_files.length() - 1; n >= 0; n--) {
|
|
f = _tmp_files[n];
|
|
if (f->id == id) {
|
|
// Found the file. Unlink and free data structs
|
|
unlink(f->file);
|
|
free(f->file);
|
|
free(f);
|
|
// Remove entry from list
|
|
_tmp_files.remove(n);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
#ifdef DEAD_WOOD
|
|
PopupCmd::PopupCmd (
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
PopupWindow * (RoamMenuWindow::* member) (void),
|
|
RoamMenuWindow *myparent
|
|
) : NoUndoCmd ( name, label, active )
|
|
{
|
|
parent=myparent;
|
|
pmpopup=member;
|
|
}
|
|
|
|
void
|
|
PopupCmd::doit()
|
|
{
|
|
PopupWindow *popup=(parent->*pmpopup)();
|
|
// popup->manage();
|
|
}
|
|
#endif /* DEAD_WOOD */
|
|
|
|
// OnItemCmd brings up the Help On Item help.
|
|
OnItemCmd::OnItemCmd ( char * name,
|
|
char *label,
|
|
int active,
|
|
UIComponent *window )
|
|
: NoUndoCmd (name, label, active)
|
|
{
|
|
_parent = window;
|
|
}
|
|
|
|
void
|
|
OnItemCmd::doit()
|
|
{
|
|
int status = DtHELP_SELECT_ERROR;
|
|
Widget widget = _parent->baseWidget();
|
|
Widget selWidget = NULL;
|
|
|
|
// Display the appropriate help information for the selected item.
|
|
|
|
status = DtHelpReturnSelectedWidgetId(widget, 0, &selWidget);
|
|
|
|
switch ((int) status) {
|
|
case DtHELP_SELECT_ERROR:
|
|
printf("Selection Error, cannot continue\n");
|
|
break;
|
|
case DtHELP_SELECT_VALID:
|
|
while (selWidget != NULL) {
|
|
if ((XtHasCallbacks(selWidget, XmNhelpCallback)
|
|
== XtCallbackHasSome)) {
|
|
XtCallCallbacks((Widget) selWidget, XmNhelpCallback, NULL);
|
|
break;
|
|
} else {
|
|
selWidget = XtParent(selWidget);
|
|
}
|
|
}
|
|
break;
|
|
case DtHELP_SELECT_ABORT:
|
|
printf("Selection Aborted by user.\n");
|
|
break;
|
|
case DtHELP_SELECT_INVALID:
|
|
printf("You must select a component within your app.\n");
|
|
break;
|
|
default:
|
|
;
|
|
// Empty
|
|
}
|
|
|
|
}
|
|
|
|
OnAppCmd::OnAppCmd ( char * name,
|
|
char *label,
|
|
int active,
|
|
UIComponent *window )
|
|
: NoUndoCmd (name, label, active)
|
|
{
|
|
_parent = window;
|
|
}
|
|
|
|
void
|
|
OnAppCmd::doit()
|
|
{
|
|
DisplayMain (_parent->baseWidget(), "Mailer", DTMAILWINDOWID);
|
|
}
|
|
|
|
TasksCmd::TasksCmd ( char * name,
|
|
char *label,
|
|
int active,
|
|
UIComponent *window )
|
|
: NoUndoCmd (name, label, active)
|
|
{
|
|
_parent = window;
|
|
}
|
|
|
|
void
|
|
TasksCmd::doit()
|
|
{
|
|
DisplayMain (_parent->baseWidget(), "Mailer", HELP_MAILER_TASKS);
|
|
}
|
|
|
|
ReferenceCmd::ReferenceCmd ( char * name,
|
|
char *label,
|
|
int active,
|
|
UIComponent *window )
|
|
: NoUndoCmd (name, label, active)
|
|
{
|
|
_parent = window;
|
|
}
|
|
|
|
void
|
|
ReferenceCmd::doit()
|
|
{
|
|
DisplayMain (_parent->baseWidget(), "Mailer", HELP_MAILER_REFERENCE);
|
|
}
|
|
|
|
UsingHelpCmd::UsingHelpCmd ( char * name,
|
|
char *label,
|
|
int active,
|
|
UIComponent *window )
|
|
: NoUndoCmd (name, label, active)
|
|
{
|
|
_parent = window;
|
|
}
|
|
|
|
void
|
|
UsingHelpCmd::doit()
|
|
{
|
|
DisplayMain (_parent->baseWidget(), "Help4Help", "_HOMETOPIC");
|
|
}
|
|
|
|
RelNoteCmd::RelNoteCmd ( char * name,
|
|
char *label,
|
|
int active,
|
|
UIComponent *window
|
|
) : NoUndoCmd (name, label, active )
|
|
{
|
|
_parent = window;
|
|
_genDialog = NULL;
|
|
}
|
|
|
|
void
|
|
RelNoteCmd::doit()
|
|
{
|
|
// int answer;
|
|
|
|
// if (!_genDialog)
|
|
// _genDialog = new DtMailGenDialog("AboutBox", _parent->baseWidget());
|
|
|
|
// _genDialog->setToAboutDialog();
|
|
// answer = _genDialog->post_and_return(GETMSG(DT_catd, 1, 92, "OK"), NULL);
|
|
|
|
DisplayMain(_parent->baseWidget(), "Mailer", "_copyright");
|
|
}
|
|
|
|
RelNoteCmd::~RelNoteCmd()
|
|
{
|
|
delete _genDialog;
|
|
}
|
|
|
|
#ifdef DEAD_WOOD
|
|
ClearCmd::ClearCmd (
|
|
char * name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : NoUndoCmd (name, label, active )
|
|
{
|
|
parent=window;
|
|
}
|
|
|
|
void
|
|
ClearCmd::doit()
|
|
{
|
|
// ((FindPopup *) parent->find_popup())->clear_text_values();
|
|
}
|
|
|
|
StartCmd::StartCmd( char *name,
|
|
char *label,
|
|
int active ) : Cmd ( name, label, active )
|
|
{
|
|
}
|
|
|
|
void
|
|
StartCmd::doit()
|
|
{
|
|
char *forward= ".forward";
|
|
|
|
struct passwd pwd;
|
|
GetPasswordEntry(pwd);
|
|
|
|
char *forward_filename=new char[strlen(pwd.pw_dir)+1+strlen(forward)+1];
|
|
sprintf( forward_filename, "%s/%s", pwd.pw_dir, forward );
|
|
}
|
|
|
|
|
|
void
|
|
StartCmd::undoit()
|
|
{
|
|
}
|
|
|
|
|
|
ChangeCmd::ChangeCmd(
|
|
char *name,
|
|
char *label,
|
|
int active
|
|
) : Cmd (name, label, active )
|
|
{
|
|
}
|
|
|
|
void
|
|
ChangeCmd::doit()
|
|
{
|
|
struct passwd pwd;
|
|
GetPasswordEntry(pwd);
|
|
|
|
char *user_name=new char[strlen(pwd.pw_name)+1];
|
|
strcpy(user_name,pwd.pw_name);
|
|
|
|
}
|
|
|
|
|
|
void
|
|
ChangeCmd::undoit()
|
|
{
|
|
}
|
|
|
|
|
|
StopCmd::StopCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window
|
|
) : Cmd (name, label, active )
|
|
{
|
|
parent=window;
|
|
}
|
|
|
|
void
|
|
StopCmd::doit()
|
|
{
|
|
unlink( parent->forwardFilename() );
|
|
parent->title( NULL );
|
|
}
|
|
|
|
|
|
void
|
|
StopCmd::undoit()
|
|
{
|
|
|
|
}
|
|
#endif /* DEAD_WOOD */
|
|
|
|
|
|
|
|
SendCmd::SendCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
SendMsgDialog *parent,
|
|
int trans_type)
|
|
: NoUndoCmd( name, label, active )
|
|
{
|
|
_parent=parent;
|
|
_default_trans = trans_type;
|
|
}
|
|
|
|
void
|
|
SendCmd::doit()
|
|
{
|
|
if (!_parent->isMsgValid())
|
|
return;
|
|
else
|
|
_parent->send_message( this->name(), _default_trans );
|
|
}
|
|
|
|
// JT - Added methods below
|
|
|
|
OpenMsgCmd::OpenMsgCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
RoamMenuWindow *window)
|
|
: RoamCmd (name, label, active, window)
|
|
{
|
|
}
|
|
|
|
void
|
|
OpenMsgCmd::doit()
|
|
{
|
|
DtMailEnv mail_error;
|
|
|
|
// Initialize the mail_error.
|
|
mail_error.clear();
|
|
|
|
_menuwindow->list()->viewInSeparateWindow(mail_error);
|
|
if (mail_error.isSet()) {
|
|
_menuwindow->postErrorDialog(mail_error);
|
|
}
|
|
|
|
}
|
|
|
|
// Attachment Cmds stuff
|
|
|
|
SaveAttachCmd::SaveAttachCmd ( char *name,
|
|
char *label,
|
|
char * title,
|
|
int active,
|
|
FileCallback save_callback,
|
|
RoamMenuWindow *clientData,
|
|
Widget parent)
|
|
:UnifiedSelectFileCmd (name,
|
|
label,
|
|
title,
|
|
GETMSG(DT_catd, 1, 93, "Save"),
|
|
active,
|
|
save_callback,
|
|
clientData,
|
|
parent)
|
|
{
|
|
_parent = clientData;
|
|
_name = NULL;
|
|
}
|
|
|
|
SaveAttachCmd::SaveAttachCmd (
|
|
char *name,
|
|
char *label,
|
|
char * title,
|
|
int active,
|
|
FileCallback save_callback,
|
|
ViewMsgDialog *clientData,
|
|
Widget parent
|
|
)
|
|
:UnifiedSelectFileCmd (name,
|
|
label,
|
|
title,
|
|
GETMSG(DT_catd, 1, 93, "Save"),
|
|
active,
|
|
save_callback,
|
|
clientData,
|
|
parent )
|
|
{
|
|
_parent = clientData;
|
|
_name = NULL;
|
|
}
|
|
|
|
SaveAttachCmd::SaveAttachCmd (
|
|
char *name,
|
|
char *label,
|
|
char * title,
|
|
int active,
|
|
FileCallback save_callback,
|
|
SendMsgDialog *clientData,
|
|
Widget parent
|
|
)
|
|
:UnifiedSelectFileCmd (name,
|
|
label,
|
|
title,
|
|
GETMSG(DT_catd, 1, 93, "Save"),
|
|
active,
|
|
save_callback,
|
|
clientData,
|
|
parent )
|
|
{
|
|
_parent = clientData;
|
|
_name = NULL;
|
|
}
|
|
|
|
void
|
|
SaveAttachCmd::doit()
|
|
{
|
|
UnifiedSelectFileCmd::doit();
|
|
|
|
DtMailEditor *editor = _parent->get_editor();
|
|
AttachArea *aa = editor->attachArea();
|
|
XmString attachmentName = aa->getSelectedAttachName();
|
|
XtVaSetValues(_fileBrowser, XmNtextString, attachmentName, NULL);
|
|
XtAddCallback ( _fileBrowser, XmNapplyCallback,
|
|
&SaveAttachCmd::updateCallback,
|
|
(XtPointer) this);
|
|
|
|
_name = XmStringCopy(attachmentName);
|
|
XmStringFree(attachmentName);
|
|
}
|
|
|
|
// Attachment Cmds stuff
|
|
|
|
|
|
void SaveAttachCmd::updateCallback(Widget, XtPointer clientData, XtPointer )
|
|
{
|
|
SaveAttachCmd *obj = (SaveAttachCmd *)clientData;
|
|
|
|
XtVaSetValues(obj->_fileBrowser, XmNtextString, obj->_name, NULL);
|
|
}
|
|
|
|
SaveAsTextCmd::SaveAsTextCmd (
|
|
char *name,
|
|
char *label,
|
|
char *title,
|
|
int active,
|
|
Editor * editor,
|
|
RoamMenuWindow *parent_roam_menu_window,
|
|
Widget parent
|
|
)
|
|
:UnifiedSelectFileCmd (name,
|
|
label,
|
|
title,
|
|
GETMSG(DT_catd, 1, 95, "Save"),
|
|
active,
|
|
fileCB,
|
|
this,
|
|
parent )
|
|
{
|
|
_text_editor = editor;
|
|
_roam_menu_window = parent_roam_menu_window;
|
|
}
|
|
|
|
SaveAsTextCmd::SaveAsTextCmd (
|
|
char *name,
|
|
char *label,
|
|
char *title,
|
|
int active,
|
|
Editor * editor,
|
|
void *,
|
|
Widget parent
|
|
)
|
|
:UnifiedSelectFileCmd (name,
|
|
label,
|
|
title,
|
|
GETMSG(DT_catd, 1, 95, "Save"),
|
|
active,
|
|
fileCB,
|
|
this,
|
|
parent )
|
|
{
|
|
_text_editor = editor;
|
|
_roam_menu_window = NULL;
|
|
}
|
|
|
|
void
|
|
SaveAsTextCmd::fileCB(void * client_data, char * selection)
|
|
{
|
|
SaveAsTextCmd * self = (SaveAsTextCmd *)client_data;
|
|
self->saveText(selection);
|
|
}
|
|
|
|
void
|
|
SaveAsTextCmd::saveText(const char * filename)
|
|
{
|
|
int answer, status;
|
|
char *buf = new char[2048];
|
|
char * helpId;
|
|
|
|
// Is it already there?
|
|
status = SafeAccess(filename, F_OK);
|
|
if (0 == status)
|
|
{
|
|
sprintf(buf,
|
|
GETMSG(DT_catd, 3, 47, "%s already exists.\nOverwrite?"),
|
|
filename);
|
|
|
|
_genDialog->setToQuestionDialog(GETMSG(DT_catd, 3, 48, "Mailer"), buf);
|
|
helpId = DTMAILHELPERROR;
|
|
answer = _genDialog->post_and_return(helpId);
|
|
if (answer==2) {
|
|
delete [] buf;
|
|
return;
|
|
}
|
|
|
|
if (unlink(filename) < 0)
|
|
{
|
|
sprintf(buf,
|
|
GETMSG(DT_catd, 3, 49, "Unable to overwrite %s.\n\
|
|
Check file permissions and retry."),
|
|
filename);
|
|
_genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 50, "Mailer"), buf);
|
|
helpId = DTMAILHELPNOOVERWRITE;
|
|
_genDialog->post_and_return(helpId);
|
|
delete [] buf;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Create or truncate, and then write the bits.
|
|
int fd = SafeOpen(filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
|
|
if (fd < 0)
|
|
{
|
|
sprintf(buf, GETMSG(DT_catd, 3, 51, "Unable to create %s."), filename);
|
|
_genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 52, "Mailer"), buf);
|
|
helpId = DTMAILHELPNOCREATE;
|
|
_genDialog->post_and_return(helpId);
|
|
delete [] buf;
|
|
return;
|
|
}
|
|
|
|
if (SafeWrite(fd, "\n", 1) < 1)
|
|
{
|
|
sprintf(buf,
|
|
GETMSG(DT_catd, 3, 53, "Unable to write to %s."),
|
|
filename);
|
|
_genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 54, "Mailer"), buf);
|
|
helpId = DTMAILHELPNOWRITE;
|
|
_genDialog->post_and_return(helpId);
|
|
SafeClose(fd);
|
|
unlink(filename);
|
|
delete [] buf;
|
|
return;
|
|
}
|
|
|
|
if (NULL == _roam_menu_window)
|
|
{
|
|
char *text_buf = _text_editor->get_contents();
|
|
writeText((XtPointer) (intptr_t) fd, text_buf);
|
|
XtFree((char*) text_buf);
|
|
}
|
|
else
|
|
writeTextFromScrolledList(fd);
|
|
|
|
SafeClose(fd);
|
|
delete [] buf;
|
|
}
|
|
|
|
void
|
|
SaveAsTextCmd::writeTextFromScrolledList(int fd)
|
|
{
|
|
static char buf[2048];
|
|
char *helpId;
|
|
char *tmppath;
|
|
DtMailEnv mail_error;
|
|
MsgScrollingList *list;
|
|
DmxMailbox *mailbox;
|
|
DmxMsg *next_msg;
|
|
|
|
//
|
|
// Create temp file.
|
|
//
|
|
char *tmpdir = new char[MAXPATHLEN+1];
|
|
snprintf(tmpdir, MAXPATHLEN+1, "%s/%s", getenv("HOME"), DtPERSONAL_TMP_DIRECTORY);
|
|
if ((tmppath = tempnam(tmpdir, "dtmail")) == NULL) {
|
|
snprintf(buf, sizeof(buf), GETMSG(DT_catd, 3, 51, "Unable to create %s."), tmpdir);
|
|
_genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 52, "Mailer"), buf);
|
|
helpId = DTMAILHELPNOCREATE;
|
|
_genDialog->post_and_return(helpId);
|
|
delete [] tmpdir;
|
|
return;
|
|
}
|
|
delete [] tmpdir;
|
|
|
|
mail_error.clear();
|
|
list = _roam_menu_window->list();
|
|
|
|
//
|
|
// Copy the selected messages to a temp file.
|
|
//
|
|
int status = list->copySelected(mail_error, tmppath, FALSE, TRUE);
|
|
if (mail_error.isSet()) {
|
|
_roam_menu_window->postErrorDialog(mail_error);
|
|
free(tmppath);
|
|
return;
|
|
}
|
|
if (0 != status) return;
|
|
|
|
mailbox = new DmxMailbox(tmppath);
|
|
mailbox->loadMessages();
|
|
next_msg = mailbox->firstMessage();
|
|
do
|
|
{
|
|
DmxPrintHeadersEnum visible_headers;
|
|
|
|
if (_roam_menu_window->fullHeader())
|
|
visible_headers = DMX_PRINT_HEADERS_ALL;
|
|
else
|
|
visible_headers = DMX_PRINT_HEADERS_ABBREV;
|
|
|
|
next_msg->display(
|
|
visible_headers,
|
|
&SaveAsTextCmd::writeText,
|
|
(XtPointer) (intptr_t) fd);
|
|
writeText((XtPointer) (intptr_t) fd, "\n\n");
|
|
} while ((next_msg = mailbox->nextMessage()) != (DmxMsg *) NULL);
|
|
delete mailbox;
|
|
|
|
//
|
|
// Clean up the temporary file.
|
|
//
|
|
unlink(tmppath);
|
|
free(tmppath);
|
|
}
|
|
|
|
void
|
|
SaveAsTextCmd::writeText(XtPointer filedes, char *text_buf)
|
|
{
|
|
long fdl = (long) filedes;
|
|
int fd = (int) fdl;
|
|
int len = strlen(text_buf);
|
|
|
|
if (SafeWrite(fd, text_buf, len) < len) {
|
|
#if 0
|
|
char buf[2048];
|
|
char *helpId;
|
|
|
|
sprintf(
|
|
buf,
|
|
GETMSG(DT_catd, 3, 53, "Unable to write to %s."),
|
|
filename);
|
|
helpId = DTMAILHELPNOWRITE;
|
|
_genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 56, "Mailer"), buf);
|
|
_genDialog->post_and_return(helpId);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void
|
|
SaveAsTextCmd::doit()
|
|
{
|
|
MsgScrollingList *list;
|
|
Widget listW;
|
|
int *pos_list = NULL;
|
|
int pos_count = 0;
|
|
|
|
if (_roam_menu_window &&
|
|
(list = _roam_menu_window->list()) &&
|
|
(listW = list->get_scrolling_list()))
|
|
{
|
|
if (!XmListGetSelectedPos(listW, &pos_list, &pos_count))
|
|
return;
|
|
|
|
if (0 == pos_count)
|
|
{
|
|
DtMailGenDialog *dialog = _roam_menu_window->genDialog();
|
|
|
|
dialog->setToErrorDialog(
|
|
GETMSG(DT_catd, 3, 50, "Mailer"),
|
|
GETMSG(DT_catd, 2, 16, "No message selected."));
|
|
dialog->post_and_return(NULL);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
UnifiedSelectFileCmd::doit();
|
|
|
|
if (1 == pos_count)
|
|
{
|
|
int pos_selected, last_space;
|
|
DtMailEnv error;
|
|
DtMailHeaderLine header;
|
|
DtMailMessageHandle msg_handle;
|
|
DtMailHeaderRequest request;
|
|
DtMail::MailBox *mbox;
|
|
|
|
pos_selected = list->get_selected_item();
|
|
msg_handle = list->msgno(pos_selected);
|
|
|
|
request.number_of_names = 1;
|
|
request.header_name = (char**) malloc(sizeof(char*));
|
|
request.header_name[0] = strdup(DtMailMessageSubject);
|
|
|
|
mbox = _roam_menu_window->mailbox();
|
|
mbox->getMessageSummary(error, msg_handle, request, header);
|
|
|
|
if (0 != header.header_values[0].length())
|
|
{
|
|
const char *orig_subject = *((header.header_values[0])[0]);
|
|
int i,j;
|
|
int orig_len = strlen(orig_subject);
|
|
char *subject = (char*) malloc(orig_len + 1);
|
|
XmString xms;
|
|
|
|
for (i=0,j=0,last_space=0; i<orig_len; i++)
|
|
{
|
|
if (isspace(orig_subject[i]))
|
|
{
|
|
if (last_space < i-1)
|
|
subject[j++] = ' ';
|
|
|
|
last_space = i;
|
|
}
|
|
else if (orig_subject[i] == '/')
|
|
subject[j++] = '\\';
|
|
else
|
|
subject[j++] = orig_subject[i];
|
|
}
|
|
subject[j] = '\0';
|
|
|
|
xms = XmStringCreateLocalized(subject);
|
|
XtVaSetValues(_fileBrowser, XmNtextString, xms, NULL);
|
|
|
|
XmStringFree(xms);
|
|
free(subject);
|
|
}
|
|
|
|
if (NULL != request.header_name)
|
|
{
|
|
if (NULL != request.header_name[0])
|
|
free(request.header_name[0]);
|
|
free(request.header_name);
|
|
}
|
|
|
|
mbox->clearMessageSummary(header);
|
|
}
|
|
}
|
|
|
|
|
|
DeleteAttachCmd::DeleteAttachCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
SendMsgDialog *smd
|
|
|
|
) : Cmd ( name, label, active )
|
|
{
|
|
_parent = smd;
|
|
}
|
|
|
|
void
|
|
DeleteAttachCmd::doit()
|
|
{
|
|
_parent->delete_selected_attachments();
|
|
}
|
|
|
|
void
|
|
DeleteAttachCmd::undoit()
|
|
{
|
|
}
|
|
|
|
UndeleteAttachCmd::UndeleteAttachCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
SendMsgDialog *smd
|
|
|
|
) : Cmd ( name, label, active )
|
|
{
|
|
_parent = smd;
|
|
}
|
|
|
|
void
|
|
UndeleteAttachCmd::doit()
|
|
{
|
|
_parent->undelete_last_deleted_attachment();
|
|
|
|
}
|
|
|
|
void
|
|
UndeleteAttachCmd::undoit()
|
|
{
|
|
}
|
|
|
|
RenameAttachCmd::RenameAttachCmd (
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
SendMsgDialog *smd
|
|
) : Cmd ( name, label, active )
|
|
{
|
|
Widget renameDialog;
|
|
XmString message;
|
|
|
|
_parent = smd;
|
|
renameDialog = XmCreatePromptDialog(
|
|
smd->baseWidget(),
|
|
"renameDialog",
|
|
NULL,
|
|
0
|
|
);
|
|
|
|
message = XmStringCreateLocalized(GETMSG(DT_catd, 1, 96, "Empty"));
|
|
XtVaSetValues(renameDialog, XmNselectionLabelString, message, NULL);
|
|
XmStringFree(message);
|
|
XmString ok_str = XmStringCreateLocalized(GETMSG(DT_catd, 1, 97, "Rename"));
|
|
XtVaSetValues(XtParent(renameDialog),
|
|
XmNtitle, GETMSG(DT_catd, 1, 98, "Mailer - Rename"),
|
|
NULL);
|
|
XtVaSetValues(renameDialog,
|
|
XmNokLabelString, ok_str,
|
|
NULL);
|
|
|
|
XmStringFree(ok_str);
|
|
XtUnmanageChild(XmSelectionBoxGetChild(renameDialog, XmDIALOG_HELP_BUTTON));
|
|
|
|
_parent->get_editor()->attachArea()->setRenameDialog(renameDialog);
|
|
XtAddCallback(renameDialog, XmNcancelCallback,
|
|
&RenameAttachCmd::cancelCallback,
|
|
(XtPointer) this );
|
|
XtAddCallback(renameDialog, XmNokCallback,
|
|
&RenameAttachCmd::okCallback,
|
|
(XtPointer) this );
|
|
}
|
|
|
|
void RenameAttachCmd::doit()
|
|
{
|
|
Widget renameDialog;
|
|
XmString oldAttachName = NULL;
|
|
XmString message;
|
|
char buf[512];
|
|
AttachArea *aa;
|
|
|
|
if (!_parent->renameAttachmentOK()) {
|
|
return;
|
|
}
|
|
|
|
aa = _parent->get_editor()->attachArea();
|
|
|
|
oldAttachName = aa->getSelectedAttachName();
|
|
|
|
if (oldAttachName == NULL) return;
|
|
|
|
renameDialog = aa->getRenameDialog();
|
|
|
|
sprintf(buf, "%s", GETMSG(DT_catd, 3, 57, "Rename attachment as"));
|
|
|
|
message = XmStringCreateLocalized(buf);
|
|
|
|
XtVaSetValues(renameDialog,
|
|
XmNselectionLabelString, message,
|
|
XmNtextString, oldAttachName,
|
|
NULL);
|
|
|
|
// XtFree(buf);
|
|
XmStringFree(message);
|
|
XmStringFree(oldAttachName);
|
|
|
|
XtManageChild(renameDialog);
|
|
XtPopup(XtParent(renameDialog), XtGrabNone);
|
|
}
|
|
|
|
void RenameAttachCmd::undoit()
|
|
{
|
|
// Just print a message that allows us to trace the execution
|
|
|
|
}
|
|
|
|
void RenameAttachCmd::cancelCallback (
|
|
Widget,
|
|
XtPointer clientData,
|
|
XtPointer callData
|
|
)
|
|
{
|
|
RenameAttachCmd *obj = (RenameAttachCmd *) clientData;
|
|
|
|
obj->cancel( callData );
|
|
}
|
|
|
|
void RenameAttachCmd::cancel( XtPointer )
|
|
{
|
|
AttachArea* aa;
|
|
|
|
aa = _parent->get_editor()->attachArea();
|
|
|
|
Widget renameDialog = aa->getRenameDialog();
|
|
|
|
XtUnmanageChild(renameDialog);
|
|
}
|
|
|
|
void RenameAttachCmd::okCallback (
|
|
Widget,
|
|
XtPointer clientData,
|
|
XtPointer callData
|
|
)
|
|
{
|
|
RenameAttachCmd *obj = (RenameAttachCmd *) clientData;
|
|
obj->ok( callData );
|
|
}
|
|
|
|
void RenameAttachCmd::ok( XtPointer callData )
|
|
{
|
|
XmSelectionBoxCallbackStruct *cbs =
|
|
(XmSelectionBoxCallbackStruct *)callData;
|
|
AttachArea *aa;
|
|
|
|
aa = _parent->get_editor()->attachArea();
|
|
|
|
Widget renameDialog = aa->getRenameDialog();
|
|
|
|
XtUnmanageChild(renameDialog);
|
|
|
|
aa->setSelectedAttachName(cbs->value);
|
|
|
|
}
|
|
|
|
AttachmentActionCmd::AttachmentActionCmd(
|
|
char *name,
|
|
char *label,
|
|
RoamMenuWindow *rmw,
|
|
int indx
|
|
) : Cmd (name, label, TRUE)
|
|
{
|
|
_index = indx;
|
|
|
|
_parent = rmw;
|
|
}
|
|
|
|
AttachmentActionCmd::AttachmentActionCmd(
|
|
char *name,
|
|
char *label,
|
|
ViewMsgDialog *vmd,
|
|
int indx
|
|
) : Cmd (name, label, TRUE)
|
|
{
|
|
_index = indx;
|
|
|
|
_parent = vmd;
|
|
}
|
|
|
|
AttachmentActionCmd::AttachmentActionCmd(
|
|
char *name,
|
|
char *label,
|
|
SendMsgDialog *smd,
|
|
int indx
|
|
) : Cmd (name, label, TRUE)
|
|
{
|
|
_index = indx;
|
|
|
|
_parent = smd;
|
|
}
|
|
|
|
|
|
void
|
|
AttachmentActionCmd::doit()
|
|
{
|
|
_parent->invokeAttachmentAction(_index);
|
|
}
|
|
|
|
void
|
|
AttachmentActionCmd::undoit()
|
|
{
|
|
}
|
|
|
|
SelectAllAttachsCmd::SelectAllAttachsCmd(
|
|
char *name,
|
|
char *label,
|
|
RoamMenuWindow *rmw
|
|
) : Cmd(name, label, TRUE)
|
|
{
|
|
_parent = rmw;
|
|
}
|
|
|
|
SelectAllAttachsCmd::SelectAllAttachsCmd(
|
|
char *name,
|
|
char *label,
|
|
ViewMsgDialog *vmd
|
|
) : Cmd(name, label, TRUE)
|
|
{
|
|
_parent = vmd;
|
|
}
|
|
|
|
SelectAllAttachsCmd::SelectAllAttachsCmd(
|
|
char *name,
|
|
char *label,
|
|
SendMsgDialog *smd
|
|
) : Cmd(name, label, FALSE)
|
|
{
|
|
_parent = smd;
|
|
}
|
|
|
|
void
|
|
SelectAllAttachsCmd::doit()
|
|
{
|
|
_parent->selectAllAttachments();
|
|
}
|
|
|
|
void
|
|
SelectAllAttachsCmd::undoit()
|
|
{
|
|
//
|
|
}
|
|
|
|
ShowAttachPaneCmd::ShowAttachPaneCmd(
|
|
char *name,
|
|
char *label,
|
|
AbstractEditorParent *aep
|
|
) : ToggleButtonCmd(name, label, TRUE)
|
|
{
|
|
_parent = aep;
|
|
}
|
|
|
|
void
|
|
ShowAttachPaneCmd::doit()
|
|
{
|
|
// If button is OFF
|
|
if (!this->getButtonState()) {
|
|
_parent->hideAttachArea();
|
|
}
|
|
else { // button is ON
|
|
_parent->showAttachArea();
|
|
}
|
|
}
|
|
|
|
void
|
|
ShowAttachPaneCmd::undoit()
|
|
{
|
|
//
|
|
}
|
|
|
|
AbbrevHeadersCmd::AbbrevHeadersCmd(
|
|
char *name,
|
|
char *label,
|
|
RoamMenuWindow *rmw
|
|
) : ToggleButtonCmd(name, label, TRUE)
|
|
{
|
|
_parent = rmw;
|
|
}
|
|
|
|
void
|
|
AbbrevHeadersCmd::doit()
|
|
{
|
|
// If button is OFF
|
|
if (!this->getButtonState()) {
|
|
_parent->fullHeader(TRUE);
|
|
}
|
|
else { // button is ON
|
|
_parent->fullHeader(FALSE);
|
|
}
|
|
}
|
|
|
|
void
|
|
AbbrevHeadersCmd::undoit()
|
|
{
|
|
//
|
|
}
|
|
|
|
CloseCmd::CloseCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
Widget w,
|
|
SendMsgDialog *s )
|
|
: NoUndoCmd(name, label, active)
|
|
{
|
|
_compose_dialog = s;
|
|
menubar_w = w;
|
|
}
|
|
|
|
void
|
|
CloseCmd::doit()
|
|
{
|
|
// Call the goAway() method on the SMD. Argument TRUE requests it
|
|
// to check if the SMD is dirty. Let it handle the
|
|
// case where text may be present in the compose window.
|
|
if (!_compose_dialog->isMsgValid())
|
|
return;
|
|
else
|
|
_compose_dialog->goAway(TRUE);
|
|
|
|
}
|
|
|
|
EditUndoCmd::EditUndoCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
AbstractEditorParent *w )
|
|
: NoUndoCmd( name, label, active )
|
|
{
|
|
editor = w->get_editor()->textEditor();
|
|
}
|
|
|
|
void
|
|
EditUndoCmd::doit()
|
|
{
|
|
editor->undo_edit();
|
|
}
|
|
|
|
EditCutCmd::EditCutCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
AbstractEditorParent *w
|
|
)
|
|
: NoUndoCmd( name, label, active )
|
|
{
|
|
editor = w->get_editor()->textEditor();
|
|
|
|
// className() is a virtual method
|
|
if (w->className() == "SendMsgDialog") {
|
|
_compose_dialog = (SendMsgDialog *)w;
|
|
}
|
|
else {
|
|
_compose_dialog = NULL;
|
|
}
|
|
}
|
|
|
|
void
|
|
EditCutCmd::doit()
|
|
{
|
|
editor->cut_selection();
|
|
|
|
if (_compose_dialog) {
|
|
// Turn Paste on
|
|
_compose_dialog->activate_edit_paste();
|
|
_compose_dialog->activate_edit_paste_indented();
|
|
_compose_dialog->activate_edit_paste_bracketed();
|
|
}
|
|
}
|
|
|
|
EditCopyCmd::EditCopyCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
AbstractEditorParent *w )
|
|
: NoUndoCmd( name, label, active )
|
|
{
|
|
editor = w->get_editor()->textEditor();
|
|
|
|
// className() is a virtual method
|
|
if (w->className() == "SendMsgDialog") {
|
|
_compose_dialog = (SendMsgDialog *)w;
|
|
}
|
|
else {
|
|
_compose_dialog = NULL;
|
|
}
|
|
}
|
|
|
|
void
|
|
EditCopyCmd::doit()
|
|
{
|
|
editor->copy_selection();
|
|
if (_compose_dialog) {
|
|
// Turn Paste on
|
|
_compose_dialog->activate_edit_paste();
|
|
_compose_dialog->activate_edit_paste_indented();
|
|
_compose_dialog->activate_edit_paste_bracketed();
|
|
}
|
|
}
|
|
|
|
EditPasteCmd::EditPasteCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
AbstractEditorParent *w )
|
|
: NoUndoCmd( name, label, active )
|
|
{
|
|
editor = w->get_editor()->textEditor();
|
|
}
|
|
|
|
void
|
|
EditPasteCmd::doit()
|
|
{
|
|
editor->paste_from_clipboard();
|
|
}
|
|
|
|
EditPasteSpecialCmd::EditPasteSpecialCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
AbstractEditorParent *w,
|
|
Editor::InsertFormat format)
|
|
: NoUndoCmd( name, label, active )
|
|
{
|
|
editor = w->get_editor()->textEditor();
|
|
insert_format = format;
|
|
}
|
|
|
|
void
|
|
EditPasteSpecialCmd::doit()
|
|
{
|
|
editor->paste_special_from_clipboard(insert_format);
|
|
}
|
|
|
|
|
|
EditClearCmd::EditClearCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
AbstractEditorParent *w )
|
|
: NoUndoCmd( name, label, active )
|
|
{
|
|
editor = w->get_editor()->textEditor();
|
|
// this->deactivate();
|
|
}
|
|
|
|
void
|
|
EditClearCmd::doit()
|
|
{
|
|
editor->clear_selection();
|
|
// Turn Paste on
|
|
// _edit_paste->activate();
|
|
}
|
|
|
|
EditDeleteCmd::EditDeleteCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
AbstractEditorParent *w )
|
|
: NoUndoCmd( name, label, active )
|
|
{
|
|
editor = w->get_editor()->textEditor();
|
|
// this->deactivate();
|
|
}
|
|
|
|
void
|
|
EditDeleteCmd::doit()
|
|
{
|
|
editor->delete_selection();
|
|
// Turn Paste off
|
|
// _edit_paste->deactivate();
|
|
}
|
|
|
|
EditSelectAllCmd::EditSelectAllCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
AbstractEditorParent *w )
|
|
: NoUndoCmd( name, label, active )
|
|
{
|
|
editor = w->get_editor()->textEditor();
|
|
}
|
|
|
|
void
|
|
EditSelectAllCmd::doit()
|
|
{
|
|
editor->select_all();
|
|
}
|
|
|
|
|
|
|
|
WordWrapCmd::WordWrapCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
AbstractEditorParent *w
|
|
) : ToggleButtonCmd( name, label, active )
|
|
{
|
|
editor = w->get_editor()->textEditor();
|
|
/*
|
|
* allow the app-defaults setting for WordWrap
|
|
*/
|
|
|
|
Widget _w = editor->get_text_widget();
|
|
Arg args[1];
|
|
|
|
XtSetArg( args[0], XmNwordWrap, &cur_setting );
|
|
XtGetValues( _w, args, 1 );
|
|
editor->set_word_wrap(cur_setting);
|
|
}
|
|
|
|
void
|
|
WordWrapCmd::doit()
|
|
{
|
|
cur_setting = ((ToggleButtonCmd *)this)->getButtonState();
|
|
editor->set_word_wrap(cur_setting);
|
|
}
|
|
|
|
Boolean
|
|
WordWrapCmd::wordWrap()
|
|
{
|
|
return(cur_setting);
|
|
}
|
|
|
|
FindChangeCmd::FindChangeCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
AbstractEditorParent *w )
|
|
: NoUndoCmd( name, label, active )
|
|
{
|
|
editor = w->get_editor()->textEditor();
|
|
}
|
|
|
|
void
|
|
FindChangeCmd::doit()
|
|
{
|
|
editor->find_change();
|
|
}
|
|
|
|
SpellCmd::SpellCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
AbstractEditorParent *w )
|
|
: NoUndoCmd( name, label, active )
|
|
{
|
|
editor = w->get_editor()->textEditor();
|
|
}
|
|
|
|
void
|
|
SpellCmd::doit()
|
|
{
|
|
editor->spell();
|
|
}
|
|
|
|
AliasCmd::AliasCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
Widget header)
|
|
: NoUndoCmd (name, label, active)
|
|
{
|
|
_header = header;
|
|
_alias = strdup(name);
|
|
}
|
|
|
|
void
|
|
AliasCmd::doit()
|
|
{
|
|
char *value;
|
|
|
|
XtVaGetValues(_header, XmNvalue, &value, NULL);
|
|
|
|
if (strlen(value))
|
|
{
|
|
char *newvalue = (char *) malloc(strlen(value) + strlen(_alias) + 3);
|
|
sprintf(newvalue, "%s, %s", value, _alias);
|
|
XtVaSetValues(_header, XmNvalue, newvalue, NULL);
|
|
free(newvalue);
|
|
}
|
|
else
|
|
XtVaSetValues(_header, XmNvalue, _alias, NULL);
|
|
|
|
XtFree(value);
|
|
}
|
|
|
|
AliasCmd::~AliasCmd()
|
|
{
|
|
free((void*) _alias);
|
|
}
|
|
|
|
|
|
OtherAliasesCmd::OtherAliasesCmd(
|
|
char *name,
|
|
char *label,
|
|
int active)
|
|
: NoUndoCmd (name, label, active)
|
|
{
|
|
_header = NULL;
|
|
}
|
|
|
|
void
|
|
OtherAliasesCmd::doit()
|
|
{
|
|
OptCmd *optCmd = (OptCmd *) theRoamApp.mailOptions();
|
|
optCmd->displayAliasesOptionsPane();
|
|
}
|
|
|
|
OtherAliasesCmd::~OtherAliasesCmd()
|
|
{
|
|
}
|
|
|
|
|
|
FormatCmd::FormatCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
AbstractEditorParent *w )
|
|
: NoUndoCmd( name, label, active )
|
|
{
|
|
editor = w->get_editor()->textEditor();
|
|
}
|
|
|
|
void
|
|
FormatCmd::doit()
|
|
{
|
|
editor->format();
|
|
}
|
|
|
|
LogMsgCmd::LogMsgCmd(
|
|
char *name,
|
|
char *label,
|
|
int active,
|
|
SendMsgDialog * send
|
|
) : ToggleButtonCmd( name, label, active )
|
|
{
|
|
// Go to props and find out the default, ie. to log or not to log.
|
|
// But for now, just look in .mailrc to see if "record" is set.
|
|
|
|
DtMailEnv error;
|
|
const char *logfile = NULL;
|
|
|
|
_send = send;
|
|
|
|
}
|
|
|
|
void
|
|
LogMsgCmd::doit()
|
|
{
|
|
if (!((ToggleButtonCmd *)this)->getButtonState()) {
|
|
// turn off logging for this message
|
|
_send->setLogState(DTM_FALSE);
|
|
}
|
|
else {
|
|
// turn on logging for this message
|
|
_send->setLogState(DTM_TRUE);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
VacationCmd::VacationCmd(
|
|
char *name,
|
|
char *label
|
|
) : Cmd (name, label, TRUE)
|
|
{
|
|
|
|
_forwardFile = ".forward";
|
|
_backupSuffix = "..BACKUP";
|
|
_subject = NULL;
|
|
_body = NULL;
|
|
_msg = NULL;
|
|
_dialog = NULL;
|
|
|
|
// Check if a .forward file exists.
|
|
|
|
_priorVacationRunning = this->priorVacationRunning();
|
|
|
|
// parse the .vacation.msg file and retain the subject
|
|
// and body.
|
|
// They need to be retrieved for display in the dialog.
|
|
|
|
this->parseVacationMessage();
|
|
}
|
|
|
|
|
|
VacationCmd::~VacationCmd()
|
|
{
|
|
if (NULL != _subject)
|
|
free((void*) _subject);
|
|
|
|
if (NULL != _msg)
|
|
delete _msg;
|
|
}
|
|
|
|
void
|
|
VacationCmd::doit()
|
|
{
|
|
}
|
|
|
|
static unsigned long
|
|
writeToFileDesc(const char * buf, int len, va_list args)
|
|
{
|
|
int fd = va_arg(args, int);
|
|
int cnt = va_arg(args, int);
|
|
int status = 0;
|
|
|
|
do {
|
|
status = SafeWrite(fd, buf, len);
|
|
} while (status < 0 && errno == EAGAIN);
|
|
|
|
return(0);
|
|
}
|
|
|
|
int
|
|
VacationCmd::startVacation(
|
|
char *subj,
|
|
char *text
|
|
)
|
|
{
|
|
int i = this->handleMessageFile(subj, text);
|
|
if (i == 0) {
|
|
i = this->handleForwardFile();
|
|
}
|
|
|
|
return (i);
|
|
}
|
|
|
|
void
|
|
VacationCmd::stopVacation()
|
|
{
|
|
char *forwardfile = new char[MAXPATHLEN+1];
|
|
|
|
snprintf(forwardfile, MAXPATHLEN+1, "%s/%s", getenv("HOME"), _forwardFile);
|
|
|
|
// Remove the current .forward file (it has vacation in it)
|
|
// Recover and replace the original backup forward file, if
|
|
// one exists.
|
|
|
|
unlink(forwardfile);
|
|
|
|
this->recoverForwardFile(forwardfile);
|
|
delete [] forwardfile;
|
|
}
|
|
|
|
Boolean
|
|
VacationCmd::priorVacationRunning()
|
|
|
|
{
|
|
char buf[256];
|
|
int fd;
|
|
Boolean retval = FALSE;
|
|
char *forwardfile = new char[MAXPATHLEN+1];
|
|
|
|
snprintf(forwardfile, MAXPATHLEN+1, "%s/%s", getenv("HOME"), _forwardFile);
|
|
|
|
if (SafeAccess(forwardfile, F_OK) != 0) {
|
|
delete [] forwardfile;
|
|
return(FALSE);
|
|
}
|
|
|
|
fd = SafeOpen(forwardfile, O_RDONLY);
|
|
|
|
buf[sizeof buf -1] = '\0';
|
|
int len;
|
|
while ((len = SafeRead(fd, buf, (sizeof buf) - 1)) > 0) {
|
|
buf[len] = 0;
|
|
if ((strstr(buf, "/usr/bin/vacation")) ||
|
|
(strstr(buf, "/usr/ucb/vacation"))) {
|
|
retval = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
SafeClose(fd);
|
|
|
|
delete [] forwardfile;
|
|
return(retval);
|
|
}
|
|
|
|
int
|
|
VacationCmd::handleForwardFile()
|
|
{
|
|
int fwd_fd;
|
|
int bkup_fd;
|
|
int fsize;
|
|
int answer;
|
|
int forwarding;
|
|
int lastchar;
|
|
caddr_t fwdptr;
|
|
char *helpId;
|
|
Boolean forwardExists;
|
|
DtMailGenDialog *dialog;
|
|
|
|
int error_bufLen = 10000;
|
|
char *error_buf = new char[error_bufLen];
|
|
char *forwardfile = new char[MAXPATHLEN+1];
|
|
char *messagefile = new char[256];
|
|
char *buf = new char[2048];
|
|
|
|
// initialize the error_buf
|
|
memset(error_buf, 0, error_bufLen);
|
|
memset(buf, 0, 2048);
|
|
|
|
answer = FALSE;
|
|
forwarding = FALSE;
|
|
forwardExists = FALSE;
|
|
|
|
passwd pw;
|
|
GetPasswordEntry(pw);
|
|
|
|
sprintf(forwardfile, "%s/%s", pw.pw_dir, _forwardFile);
|
|
|
|
if (SafeAccess(forwardfile, F_OK) == 0 ) {
|
|
forwardExists = TRUE;
|
|
}
|
|
else {
|
|
forwardExists = FALSE;
|
|
}
|
|
|
|
if (forwardExists && !_priorVacationRunning) {
|
|
|
|
/* STRING_EXTRACTION -
|
|
*
|
|
* This confirmation window is brought up when the user
|
|
* tries to update the vacation status when the user is
|
|
* already using a .forward file.
|
|
*/
|
|
if (NULL != _dialog)
|
|
dialog = _dialog;
|
|
else
|
|
dialog = theRoamApp.genDialog();
|
|
|
|
sprintf(error_buf, "%s", GETMSG(DT_catd, 1, 102, "You are already using the forwarding facility for\nsomething other than Vacation. While Vacation is\nrunning, Vacation will be appended to this other\nforwarding activity. Is it still OK to start Vacation?\0"));
|
|
|
|
dialog->setToQuestionDialog(GETMSG(DT_catd, 1, 103, "Mailer"),
|
|
error_buf);
|
|
|
|
helpId = DTMAILHELPOKSTARTVACATION;
|
|
answer = dialog->post_and_return(helpId);
|
|
|
|
if (answer == 2) {// Cancel chosen
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
return 1;
|
|
}
|
|
|
|
if (this->backupFile(forwardfile) < 0) {
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
return 1;
|
|
}
|
|
|
|
/* A .forward file is currently in use. Merge vacation
|
|
* into this file, rather than overwrite it. To do so,
|
|
* set the appropriate variable to indicate mode.
|
|
*/
|
|
|
|
_priorVacationRunning = TRUE;
|
|
|
|
// Turn on the bit to indicate we are currently using a .forward
|
|
forwarding = TRUE;
|
|
}
|
|
else if (forwardExists && _priorVacationRunning) {
|
|
|
|
/* STRING_EXTRACTION -
|
|
*
|
|
* This confirmation window is brought up when the user
|
|
* tries to update the vacation status when the user is
|
|
* already using a .forward file.
|
|
*/
|
|
|
|
if (NULL != _dialog)
|
|
dialog = _dialog;
|
|
else
|
|
dialog = theRoamApp.genDialog();
|
|
|
|
sprintf(error_buf, "%s", GETMSG(DT_catd, 1, 104, "You are already running the vacation program in your .forward file.\nConsult documentation on how to stop it and remove it from your .forward file.\nTry this command after fixing that problem.\0"));
|
|
|
|
dialog->setToErrorDialog("Error", error_buf);
|
|
helpId = DTMAILHELPREMOVEVACATION;
|
|
answer = dialog->post_and_return(helpId);
|
|
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
return 1;
|
|
|
|
}
|
|
|
|
// Re-initialize the error_buf
|
|
memset(error_buf, 0, error_bufLen);
|
|
|
|
sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
|
|
|
|
if (forwardExists) {
|
|
fwd_fd = SafeOpen(forwardfile, O_WRONLY | O_APPEND | O_CREAT);
|
|
}
|
|
else {
|
|
fwd_fd = SafeOpen(forwardfile, O_WRONLY | O_CREAT);
|
|
}
|
|
|
|
if (fwd_fd < 0 ) {// If fwdfile is not writable/appendable
|
|
|
|
// Put up error dialog indicating fwdfile not writable
|
|
/* restore the original .forward file */
|
|
|
|
this->recoverForwardFile(forwardfile);
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
return 1;
|
|
}
|
|
|
|
SafeFChmod(fwd_fd, 0644);
|
|
|
|
// Make buf be forwardfile._backupSuffix.
|
|
// Then create a backup file of name buf
|
|
|
|
strcpy(buf, forwardfile);
|
|
strcat(buf, _backupSuffix);
|
|
|
|
// If we are currently using a .forward then we need to append/prepend
|
|
// the vacation command
|
|
|
|
if (forwarding) {
|
|
|
|
/* CREATE NEW .forward FILE
|
|
*
|
|
* The original .forward file has been renamed to the
|
|
* backup file name. We need to open the backup .forward
|
|
* file so we can copy from it.
|
|
*/
|
|
|
|
if ((bkup_fd = SafeOpen(buf, O_RDONLY)) < 0) {
|
|
/* restore the original .forward file */
|
|
if (answer)
|
|
this->recoverForwardFile(forwardfile);
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
return 1;
|
|
}
|
|
|
|
/* COPY OLD .forward TO NEW .forward
|
|
*
|
|
* Using mmap is quite fast, so rather than do a while
|
|
* loop to copy line by line, we'll use mmap followed by
|
|
* a write.
|
|
*/
|
|
|
|
fsize= (int)lseek(bkup_fd, 0, SEEK_END);
|
|
if (fsize > 0)
|
|
{
|
|
fwdptr =
|
|
(caddr_t) mmap(0, fsize, PROT_READ, MAP_PRIVATE, bkup_fd, 0);
|
|
|
|
// If map failed
|
|
if (fwdptr == (char *)-1) {
|
|
// error
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
SafeClose(bkup_fd);
|
|
return 1;
|
|
}
|
|
|
|
// If write failed
|
|
if (SafeWrite(fwd_fd, fwdptr, fsize) < fsize) {
|
|
// error
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
SafeClose(bkup_fd);
|
|
return 1;
|
|
}
|
|
|
|
/* RELEASE .forward FILE
|
|
*
|
|
* Un-mmap the new .forward file
|
|
*/
|
|
|
|
lastchar = fwdptr[fsize-1];
|
|
munmap(fwdptr, fsize);
|
|
}
|
|
else
|
|
lastchar = '\n';
|
|
|
|
/* APPEND VACATION LINE
|
|
*
|
|
* The new .forward file is still open, so append the
|
|
* new line below as the last line of the .forward file.
|
|
* Check to make sure last character in the file is a
|
|
* newline. If it's not, add one so our work goes on
|
|
* a separate line.
|
|
*/
|
|
|
|
if (lastchar != '\n') {
|
|
lseek(fwd_fd, 0, SEEK_END);
|
|
char *txt = "\n";
|
|
if (SafeWrite(fwd_fd, txt, strlen(txt)) < strlen(txt)) {
|
|
// error
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
SafeClose(bkup_fd);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Now, add the vacation line to the next line.
|
|
*/
|
|
char *append_buf1 = new char[1024*2];
|
|
sprintf(append_buf1, "|\" /usr/bin/vacation %s\"\n", pw.pw_name);
|
|
|
|
if (SafeWrite(fwd_fd, append_buf1, strlen(append_buf1)) <
|
|
strlen(append_buf1)) {
|
|
// error
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
delete [] append_buf1;
|
|
SafeClose(bkup_fd);
|
|
return 1;
|
|
}
|
|
delete [] append_buf1;
|
|
|
|
SafeClose(bkup_fd);
|
|
}
|
|
|
|
/* Create known backup file. The known backup
|
|
* file allows mailtool to differentiate between
|
|
* vacation being started from mailtool, and vacation
|
|
* being invoked (the Unix program as opposed to the
|
|
* MailTool Vacation menu item) via tty session.
|
|
*/
|
|
|
|
if (!forwardExists) {
|
|
|
|
if ((bkup_fd = SafeOpen(buf, O_WRONLY | O_APPEND | O_CREAT)) < 0) {
|
|
/* restore the original .forward file */
|
|
if (answer)
|
|
this->recoverForwardFile(forwardfile);
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
SafeClose(fwd_fd);
|
|
return 1;
|
|
}
|
|
|
|
char *end_text = "User not using forward file\n";
|
|
|
|
if (SafeWrite(bkup_fd, end_text, strlen(end_text)) <
|
|
strlen(end_text)) {
|
|
// error
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
SafeClose(bkup_fd);
|
|
SafeClose(fwd_fd);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (!forwardExists) {
|
|
|
|
/* WRITE NEW .forward FILE
|
|
*
|
|
* There was no .forward file, so no appending
|
|
* must be done. Simply write the standard
|
|
* vacation line into the new .forward file.
|
|
*/
|
|
|
|
char *append_buf2 = new char[1024*2];
|
|
|
|
sprintf(append_buf2, "\\%s, |\" /usr/bin/vacation %s\"\n",
|
|
pw.pw_name, pw.pw_name);
|
|
if (SafeWrite(fwd_fd, append_buf2, strlen(append_buf2)) <
|
|
strlen(append_buf2)) {
|
|
// error
|
|
SafeClose(bkup_fd);
|
|
SafeClose(fwd_fd);
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
delete [] append_buf2;
|
|
return 1;
|
|
}
|
|
delete [] append_buf2;
|
|
}
|
|
|
|
SafeClose(bkup_fd);
|
|
SafeClose(fwd_fd);
|
|
|
|
system("/usr/bin/vacation -I");
|
|
|
|
delete [] buf;
|
|
delete [] messagefile;
|
|
delete [] error_buf;
|
|
delete [] forwardfile;
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
VacationCmd::backupFile(
|
|
char *file
|
|
)
|
|
{
|
|
char *buf = new char[MAXPATHLEN+1];
|
|
|
|
strcpy(buf, file);
|
|
strcat(buf, _backupSuffix);
|
|
|
|
if (rename(file, buf) < 0) {
|
|
/* STRING_EXTRACTION -
|
|
*
|
|
* We tried to make a backup copy of your .forward file, but
|
|
* it failed. The first %s is the name of the rename
|
|
* target; the second %s is the system error string.
|
|
*/
|
|
|
|
// Put up error dialog
|
|
delete [] buf;
|
|
return(-1);
|
|
}
|
|
|
|
delete [] buf;
|
|
return(0);
|
|
}
|
|
|
|
int
|
|
VacationCmd::recoverForwardFile(
|
|
char *file
|
|
)
|
|
{
|
|
char *buf = new char[BUFSIZ+1];
|
|
int fd;
|
|
|
|
sprintf(buf, "%s", file);
|
|
strcat(buf, _backupSuffix);
|
|
|
|
if (rename(buf, file) < 0) {
|
|
|
|
/* STRING_EXTRACTION -
|
|
*
|
|
* We tried to restore your original .forward file, but could
|
|
* not. The first %s is the name of the original .forward file,
|
|
* the second %s is the the system error string.
|
|
*/
|
|
|
|
// Handle dialog indicating error in recovering .forward file.
|
|
// Error usually caused by starting /usr/bin/vacation outside
|
|
// of dtmail
|
|
|
|
delete [] buf;
|
|
return(-1);
|
|
}
|
|
|
|
if ((fd = SafeOpen(file, O_RDONLY)) == -1) {
|
|
delete [] buf;
|
|
return(-1);
|
|
}
|
|
|
|
buf[sizeof file -1] = '\0';
|
|
while (SafeRead(fd, buf, BUFSIZ) != 0) {
|
|
if (strstr(buf, "User not using forward file")) {
|
|
unlink(file);
|
|
break;
|
|
}
|
|
}
|
|
|
|
SafeClose(fd);
|
|
|
|
delete [] buf;
|
|
return(0);
|
|
}
|
|
|
|
char *
|
|
VacationCmd::subject()
|
|
{
|
|
return(_subject);
|
|
}
|
|
|
|
|
|
char *
|
|
VacationCmd::body()
|
|
{
|
|
if (_body) {
|
|
return((char *)_body);
|
|
}
|
|
else {
|
|
return(NULL);
|
|
}
|
|
}
|
|
|
|
void
|
|
VacationCmd::parseVacationMessage()
|
|
{
|
|
passwd pw;
|
|
int fd;
|
|
|
|
DtMailGenDialog *dialog;
|
|
char * helpId;
|
|
int answer;
|
|
char dialog_text[1024*4];
|
|
DtMailEnv error;
|
|
DtMail::Session * d_session = theRoamApp.session()->session();
|
|
DtMailBuffer mbuf;
|
|
|
|
if (NULL != _dialog)
|
|
dialog = _dialog;
|
|
else
|
|
dialog = theRoamApp.genDialog();
|
|
|
|
GetPasswordEntry(pw);
|
|
|
|
char *messagefile = new char[MAXPATHLEN+1];
|
|
sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
|
|
|
|
// See if the messagefile exists.
|
|
// If it doesn't create one and throw in the text found in the
|
|
// properties sheet. If no text found, use default template.
|
|
|
|
char * fullpath = d_session->expandPath(error, messagefile);
|
|
delete [] messagefile;
|
|
messagefile = NULL;
|
|
|
|
// 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.
|
|
//
|
|
|
|
fd = SafeOpen(fullpath, O_RDONLY);
|
|
free(fullpath);
|
|
|
|
if (fd < 0) {// File doesn't exist
|
|
|
|
_subject = NULL;
|
|
_body = NULL;
|
|
return;
|
|
}
|
|
|
|
struct stat buf;
|
|
if (SafeFStat(fd, &buf) < 0) {
|
|
|
|
sprintf(dialog_text, "%s",
|
|
GETMSG(DT_catd, 1, 105, "Cannot open .vacation.msg file -- No write permission."));
|
|
dialog->setToQuestionDialog("Mailer", dialog_text);
|
|
helpId = DTMAILHELPNOWRITEVACATION;
|
|
answer = dialog->post_and_return(helpId);
|
|
|
|
_subject = NULL;
|
|
_body = NULL;
|
|
|
|
SafeClose(fd);
|
|
return;
|
|
}
|
|
|
|
int page_size = (int)sysconf(_SC_PAGESIZE);
|
|
size_t map_size = (int) (buf.st_size +
|
|
(page_size - (buf.st_size % page_size)));
|
|
|
|
if (buf.st_size == 0) {
|
|
SafeClose(fd);
|
|
return;
|
|
}
|
|
|
|
int free_buf = 0;
|
|
mbuf.size = buf.st_size;
|
|
mbuf.buffer = mmap(0, map_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
if (mbuf.buffer == (char *)-1) {
|
|
free_buf = 1;
|
|
mbuf.buffer = new char[mbuf.size];
|
|
if (mbuf.buffer == NULL) {
|
|
dialog->setToErrorDialog(GETMSG(DT_catd, 3, 59, "No Memory"),
|
|
GETMSG(DT_catd, 3, 60, "There is not enough memory to load the existing .vacation.msg file."));
|
|
helpId = DTMAILHELPNOLOADVACATION;
|
|
answer = dialog->post_and_return(helpId);
|
|
SafeClose(fd);
|
|
|
|
_subject = NULL;
|
|
_body = NULL;
|
|
|
|
return;
|
|
}
|
|
|
|
if (SafeRead(fd, mbuf.buffer, (unsigned int)mbuf.size) < mbuf.size) {
|
|
dialog->setToErrorDialog(GETMSG(DT_catd, 3, 61, "Mailer"),
|
|
GETMSG(DT_catd, 3, 62, "The existing .vacation.msg file appears to be corrupt."));
|
|
helpId = DTMAILHELPCORRUPTVACATION;
|
|
answer = dialog->post_and_return(helpId);
|
|
SafeClose(fd);
|
|
delete (char*) mbuf.buffer;
|
|
_subject = NULL;
|
|
_body = NULL;
|
|
|
|
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);
|
|
SafeClose(fd);
|
|
|
|
if (error.isSet()) {
|
|
_subject = NULL;
|
|
_body = NULL;
|
|
_msg = NULL;
|
|
return;
|
|
}
|
|
else {
|
|
DtMail::Envelope * env = msg->getEnvelope(error);
|
|
DtMailHeaderHandle hnd;
|
|
|
|
int hcount = 0;
|
|
char * name;
|
|
DtMailValueSeq value;
|
|
|
|
for (hnd = env->getFirstHeader(error, &name, value);
|
|
error.isNotSet() && hnd;
|
|
hnd = env->getNextHeader(error, hnd, &name, value)) {
|
|
|
|
if (!strcmp(name, "Subject") == 0) {
|
|
continue;
|
|
}
|
|
else {
|
|
|
|
int max_len = 0;
|
|
for (int slen = 0; slen < value.length(); slen++) {
|
|
max_len += strlen(*(value[slen]));
|
|
}
|
|
|
|
char * new_str = new char[max_len + (value.length() * 3)];
|
|
|
|
strcpy(new_str, "");
|
|
for (int copy = 0; copy < value.length(); copy++) {
|
|
if (copy != 0) {
|
|
strcat(new_str, " ");
|
|
}
|
|
|
|
strcat(new_str, *(value[copy]));
|
|
}
|
|
|
|
_subject = strdup(new_str);
|
|
value.clear();
|
|
free(name);
|
|
delete [] new_str;
|
|
break;
|
|
}
|
|
}
|
|
|
|
DtMail::BodyPart * bp = msg->getFirstBodyPart(error);
|
|
if (error.isNotSet()) {
|
|
unsigned long length;
|
|
|
|
bp->getContents(error,
|
|
&_body,
|
|
&length,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
}
|
|
|
|
//
|
|
// Avoid a memory leak.
|
|
//
|
|
_msg = msg;
|
|
}
|
|
|
|
}
|
|
|
|
int
|
|
VacationCmd::handleMessageFile(
|
|
char *subj,
|
|
char *text
|
|
)
|
|
{
|
|
int fd;
|
|
|
|
DtMailGenDialog *dialog;
|
|
char * helpId;
|
|
int answer;
|
|
char dialog_text[1024*4];
|
|
Boolean text_changed = FALSE;
|
|
char *messagefile = new char[256];
|
|
|
|
BufferMemory buf(4096);
|
|
|
|
if (NULL != _dialog)
|
|
dialog = _dialog;
|
|
else
|
|
dialog = theRoamApp.genDialog();
|
|
|
|
// Check if a .forward file exists.
|
|
passwd pw;
|
|
GetPasswordEntry(pw);
|
|
|
|
sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
|
|
|
|
// See if the messagefile exists.
|
|
// If it doesn't create one and throw in the text found in the
|
|
// properties sheet. If no text found, use default template.
|
|
|
|
answer = 0;
|
|
|
|
int msg_file_exists = SafeAccess(messagefile, F_OK);
|
|
if (subj != NULL) {
|
|
if (_subject == NULL || strcmp(_subject, subj) != 0)
|
|
text_changed = TRUE;
|
|
}
|
|
else if (_subject != NULL)
|
|
text_changed = TRUE;
|
|
|
|
if (!text_changed) {
|
|
if (text != NULL) {
|
|
if (_body == NULL || strcmp((char*)_body, text) != 0)
|
|
text_changed = TRUE;
|
|
}
|
|
else if (_body != NULL)
|
|
text_changed = TRUE;
|
|
}
|
|
|
|
if (msg_file_exists >= 0 && text_changed) {
|
|
sprintf(dialog_text, "%s",
|
|
GETMSG(DT_catd, 1, 106, ".vacation.msg file exists. Replace with new text?"));
|
|
dialog->setToQuestionDialog("Mailer", dialog_text);
|
|
helpId = DTMAILHELPEXISTSVACATION;
|
|
answer = dialog->post_and_return(helpId);
|
|
|
|
if (answer == 1) {
|
|
// backup the messageFile
|
|
this->backupFile(messagefile);
|
|
}
|
|
}
|
|
|
|
// If the file doesn't exist or if the user has okayed creation
|
|
|
|
if ((msg_file_exists < 0) || (answer == 1)) {
|
|
|
|
fd = SafeOpen(messagefile, O_WRONLY | O_CREAT);
|
|
if (fd < 0) {
|
|
sprintf(dialog_text, "%s",
|
|
GETMSG(DT_catd, 1, 107, "Cannot open .vacation.msg file -- No write permission."));
|
|
dialog->setToQuestionDialog("Mailer", dialog_text);
|
|
helpId = DTMAILHELPERROR;
|
|
answer = dialog->post_and_return(helpId);
|
|
|
|
// Handle dialog indicating file not writable
|
|
delete [] messagefile;
|
|
return (-1);
|
|
}
|
|
SafeFChmod (fd, 0644);
|
|
|
|
if (!subj) {
|
|
/* NL_COMMENT
|
|
* This is the default value of the subject field in the
|
|
* message that gets returned to the sender when vacation
|
|
* is turned on.
|
|
*/
|
|
subj = GETMSG(DT_catd, 1, 108, "I am on vacation");
|
|
} else {
|
|
buf.appendData("Subject: ", 9);
|
|
buf.appendData(subj, strlen(subj));
|
|
buf.appendData("\nPrecedence: junk\n\n", 19);
|
|
}
|
|
if (_subject)
|
|
free (_subject);
|
|
_subject = strdup(subj);
|
|
|
|
if (!text) {
|
|
text = GETMSG(DT_catd, 1, 109,
|
|
"I'm on vacation.\nYour mail regarding \"$SUBJECT\" will be read when I return.\n");
|
|
}
|
|
buf.appendData(text, strlen(text));
|
|
if (strlen(text) > 0 && text[strlen(text) - 1] != '\n') {
|
|
buf.appendData("\n", 1);
|
|
}
|
|
_body = strdup(text);
|
|
|
|
buf.iterate(writeToFileDesc, fd);
|
|
|
|
SafeClose(fd);
|
|
}
|
|
delete [] messagefile;
|
|
return(0);
|
|
}
|